반환값을 반환하는 방법
샤이니 앱을 만들 때 필요한 가장 중요한 R언어 지식은 아무래도 R 함수이다. 특히 샤이니 앱을 만들 때 R에서 두가지 방법으로 함수가 값을 반환한다는 사실을 아는 것이 중요하다.
R 함수의 반환 값은 다음 두 가지 방법 중 하나로 반환된다.
- return() 함수를 사용한 명시적인 방법
- 함수 몸체(body)에서 가장 마지막 표현식의 값
다음은 두 방법으로 각각의 함수를 정의한 것이다. 차이는 없다.
> sq1 <- function(x) return(x*x)
> sq2 <- function(x) x*x
함수 안에는 if같은 조건문을 써서 함수를 일부러 빠져나가게 할 필요가 있을 때는 return()함수를 명시적으로 사용한다.
그러나 대부분의 경우에는 두 번째 방법인 마지막 표현식을 반환값으로 사용한다.
R에서 하나의 함수는 하나의 객체만을 반환할 수 있다. 이는 R의 규칙이다. 만약 여러가지 객체를 반환해야 하는 경우라면, 리스트(list)와 같은 객체로 그 객체들을 묶어서 하나의 리스트로 반환해야 한다. R에서 lm() 함수와 같은 통계 분석을 위한 함수는 대부분 이런 방법을 통해서 결과를 반환한다.
샤이니 앱에서 사용되는 함수 중에 tagList() 라는 함수가 있다. 이것은 UI 요소들을 다이내믹하게 출력할 때 필요한 것으로, 여러 개의 UI를 반환하고 싶을 때 일반적인 리스트처럼 하나로 묶어서 반환할 수 있다.
반환값과 부수효과의 차이
R에서 어떤일이 벌어지는 것은 모두 함수 호출에 의한 것이다. 우리가 함수를 실행하는 이유는 두 가지로 요약할 수 있다.
- 첫째, 반환값(return value)를 얻는다.
- 둘째, 부수효과(side effect)를 얻는다.
반환값과 부수효과가 무엇인지 알아보자. R에서 함수를 호출하면 값이 반환된다. NULL 값이 반환되는 경우도 있지만 이것도 하나의 값으로 보면, 모든 함수 호출은 값을 반환한다.
> x <- mean(1:10)
> x
[1] 5.5
함수는 값을 반환할 뿐만 아니라 부수효과를 낼 수도 있다. 다시 이야기하자면 R에서 모든 함수는 값을 반환하고, 어떤 함수는 값을 반환하기도 하지만 부수효과도 낸다. 부수효과는 플롯이 될 수도 있고, 콘솔에 대한 출력이 될 수도 있다. 즉 실행되는 함수의 입장에서 함수 밖의 세계에 어떤 영향을 주는 것을 부수효과라고 한다. print() 함수를 예로 들어보자. 다음과 같이 하면 R 콘솔에 값이 인쇄되는데 이것은 부수효과이다.
> print("abc")
[1] "abc"
다음 코드를 보자. 이 코드는 콘솔에 출력하고(부수효과) 값도 반환되어 이것이 x에 할당된다(값의 반환)
> x <- print("abc")
[1] "abc"
> x
[1] "abc"
또 다른 예는 hist() 함수이다. 이 함수는 그래픽 디바이스에 플롯을 출력하기도 하지만 다음과 같이 하면 플롯에 대한 정보들이 저장되기도 한다.
> his <- hist(rnorm(1000))
> his
$breaks
[1] -3.5 -3.0 -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0
[15] 3.5
$counts
[1] 2 3 11 56 101 152 194 175 144 93 50 10 8 1
$density
[1] 0.004 0.006 0.022 0.112 0.202 0.304 0.388 0.350 0.288 0.186 0.100 0.020
[13] 0.016 0.002
$mids
[1] -3.25 -2.75 -2.25 -1.75 -1.25 -0.75 -0.25 0.25 0.75 1.25 1.75 2.25
[13] 2.75 3.25
$xname
[1] "rnorm(1000)"
$equidist
[1] TRUE
attr(,"class")
[1] "histogram"
그래픽 출력은 부수효과이고, 변수에 할당되는 것은 값의 반환에 의한 것이다. 이렇게 반환값과 부수효과의 차이를 알면, 샤이니 앱을 구성하는 요소 중에서 반응성 표현식(reactive expression)과 관찰자(reactive observer)의 차이를 더 잘 이해할 수 있다. 반응성 표현식은 값을 반환하고 관찰자는 부수효과를 낸다. 반응성 표현식은 reactive({}) 함수로 만들고, 관찰자는 observe({}) 함수로 만든다.
함수들을 하나의 리스트로 묶기
R에서 함수는 일반 객체와 똑같이 취급된다. 함수는 소위 'first - class citizen'으로 취급된다고 한다. 그래서 변수에 할당되고 , 다른 함수의 인자로 사용되고, 다른 함수의 반환값으로 사용되기도 한다. R은 함수형 프로그래밍 언어로서, 함수도 객체의 한 종류이다.
또한 이러한 이유로 함수들을 하나의 리스트로 묶어서 관리할 수 있으며 다음과 같은 코딩을 할 수 있다. fns 라는 리스트에 필요한 함수들을 저장한다. 다음은 어떤 함수들을 lapply() 함수를 사용하여 주어진 값에 대해서 하나씩 적용한 것이다.
> set.seed(2017)
> fns <- list(mean,median,sd,var,min,max)
> x <- sample(c(1:100),30,replace = TRUE)
> unlist(lapply(fns, function(f) f(x)))
[1] 51.16667 52.50000 29.76469 28.00000 5.00000 30.00000 100.00000
[8] 37.00000 85.00000 18.00000 86.00000 96.00000 26.00000 33.00000
[15] 5.00000 29.00000 89.00000 1.00000 56.00000 57.00000 70.00000
[22] 86.00000 63.00000 44.00000 72.00000 69.00000 40.00000 86.00000
[29] 49.00000 8.00000 71.00000 68.00000 28.00000 1.00000 100.00000
https://blog.naver.com/sw4r/221128187959 <- lapply()에 대해 잘 설명한 블로그 주소.
샤이니에는 tags라는 리스트에 HTML 요소들을 만들 수 있는 함수들이 저장되어 있다. 이를테면 <p> 라는 HTML 요소를 만들 때는 tags$p()라는 함수를 사용한다. <p> 처럼 흔하게 사용하는 함수는 그냥 p()라고 쓸 수도 있지만, 기본적으로는 tags$p() 와 같은 형태를 사용한다. 일반 리스트 요소에 접근하는 방법과 같이 $를 사용하고 끝에 () 를 붙여서 함수를 호출한다.
'전공 > R프로그래밍' 카테고리의 다른 글
R프로그래밍 17. 느긋한 평가 조급한 평가 (0) | 2019.08.06 |
---|---|
R프로그래밍 16.R 환경 (0) | 2019.08.01 |
R프로그래밍 14. $,[[,[ 의 차이점 (0) | 2019.07.22 |
R 프로그래밍 13. 데이터 프레임 서브 세팅 (0) | 2019.07.10 |
R 프로그래밍 12. R에 내장된 데이터셋 (0) | 2019.07.04 |