재현가능한 과학적 분석을 위한 R
R과 RStudio 소개
학습 목표
- RStudio IDE 개발환경에 나온 다양한 창에 친숙해진다.
- RStudio IDE 개발환경에 활용되는 버튼, 단축키, 선택옵션과 친숙해진다.
- 변수를 이해하고, 변수에 값을 할당하는 방법을 이해한다.
- 인터랙티브 R 세션에 작업공간을 관리할 수 있다.
- 수학 연산과 비교연산 작업을 수행할 수 있다.
- 함수를 호출할 수 있다.
- 팩키지 관리에 대한 소개
RStudio 소개
소프트웨어 카펜트리 R교육에 오신 것을 환영합니다.
이번 R 수업시간을 통해서, R 언어 기본기 뿐만 아니라 저녁이 있는 삶을 가능토록 과학 프로젝트에 코드를 구조화하는 모범 활용사례도 교육한다.
도구로 RStudio 를 사용한다: 자유로이 사용가능하고, 무료이며, 오픈 소스 R과 통합된 개발 환경을 제공한다. RStudio는 편집기가 내장되어 있고, (서버 포함) 모든 플랫폼에서 동작하고, 버젼 제어 및 프로젝트 관리 같은 많은 앞선 기능을 제공한다.
기본 배치
RStudio를 처음 열게 되면, 창 3개가 반갑게 여러분을 맞이한다:
- 인터랙티브 R 콘솔 : 좌측 전체
- 작업공간(Workspace)/이력 (History) : 우측상단 탭
- 파일(File)/그래프(Plot)/팩키지(Package)/도움말(Help): 우측하단 탭
R 스크립트 같은 파일을 열게 되면, 편집창이 좌측 상단에 열린다.
RStudio 내부 작업흐름
RStudio 내부에서 작업하는 방식이 크게 두가지 있다.
- 인터랙티브 R 콘솔에서 테스트하고 가지고 놀다가, 나중에 실행할
.R
파일에 복사해서 붙여넣는다.
- 초기 시작하고 작은 테스트를 할 때 잘 작동한다.
- 신속하게 노동 집약적인 개발이 된다.
.R
파일에서 작업을 시작하고, RStudio 명령어/단축키를 사용해서 현재 라인, 선택된 라인 혹은 변경된 라인을 인터랙티브 R 콘솔에 밀어넣어 실행한다.
- 시작하는 매우 훌륭한 방식이다; 작성된 모든 코드가 나중에 저장된다.
- RStudio 내부 혹은 R
source()
함수를 사용해서 생성한 파일을 실행할 수 있다.
R 소개
R에서 상당한 시간을 R 인터랙티브 콘솔에서 사용한다. 이곳이 여러분이 작성한 모든 코드를 실행하는 곳으로 R 스크립트 파일에 추가하기 전에, 아이디어를 시험하는 유용한 환경이다. RStudio 콘솔은 R
명령-라인 환경에서 입력하는 곳과 동일하다.
R 인터랙티브 세션에서 보게 되는 첫번째 사항은 정보가 쭉 나오고 나서, “>” 가 나타나고 커서가 깜빡인다. 여러가지 면에서, 쉘 수업시간에 학습한 쉘 환경과 유사하다: REPL 루프(읽고, 평가하고, 출력하는 루프) 기본 아이디어 위에서 동작한다. 명령어를 입력하면, R이 명령어를 실행하고 나서, 결과를 반환한다.
계산기로 R 사용하기
R로 할 수 있는 가장 간단한 것이 산수다:
1 + 100
[1] 101
R이 “[1]” 다음에 정답을 출력한다. 지금 당장 “[1]”에 대해 걱정하지 말자. 나중에 설명이 나와 있다. 지금은 일단 출력결과를 지칭한다고 생각한다.
배쉬(bash) 처럼, 불완전한 명령어를 타이핑하면, R은 사용자가 명령어를 완성할 때까지 대기한다:
> 1 +
+
1+
다음에 엔터
를 치게되면, R 세션이 “>” 대신에 “+” 을 보여준다. 이것이 의미하는 바는 명령어가 완성될 때까지 대기한다는 것이다. 명령어를 취소하고자 한다면, 단순히 “Esc” 키를 치게 되면, 다시 “>” 프롬프트로 되돌아 간다.
계산기로 R을 사용할 때, 연산 순위는 초중등학교에서 배운 것과 동일하다.
가장 우선순위가 높은 것부터 낮은 순서는 다음과 같다:
- 괄호:
(
,)
- 멱승:
^
or**
- 나눗셈:
/
- 곱셈:
*
- 덧셈:
+
- 뺄셈:
-
3 + 5 * 2
[1] 13
괄호를 사용해서 연산작업을 한데 묶는데, 이유는 의도한 바를 명확히 하거나, 기본설정과 차이가 날 때 평가순서를 강제하기 위해서다.
(3 + 5) * 2
[1] 16
꼭 필요하지 않을 때 괄호가 사용되면 읽기 힘들어 지기도 하지만, 의도를 명확히 한다. 나중에 여러분이 작성한 코드를 다른 사람이 읽게 됨을 기억하라.
(3 + (5 * (2 ^ 2))) # 읽기 어렵다.
3 + 5 * 2 ^ 2 # 만약 수학 연산 우선순위 규칙을 기억한다면, 명확한다.
3 + 5 * (2 ^ 2) # 우선순위 규칙을 잊어버린 경우, 도움이 된다.
상기 코드 각 라인 뒤에 텍스트를 “주석”이라고 부른다. 해쉬(혹은 번호기호)기호 #
다음에 오는 모든 것은 코드가 실행될 때 R에서 무시된다.
매우 작거나 큰 숫자는 과학 표기법을 따른다:
2/10000
[1] 2e-04
상기 표기법은 10^XX
곱한 것을 축약한 것이다. 따라서, 2e-4
은 2 * 10^(-4)
을 축약한 것이다.
숫자를 과학 표기법으로 작성할 수도 있다:
5e3 # 양수는 음의 부호가 생략됨에 주의
[1] 5000
수학 함수
R에는 수많은 내장 수학함수가 존재한다. 함수를 호출하려면, 함수명을 단순히 타이핑하고, 괄호를 열고 닫으면 된다. 괄호안에 타이핑하는 것을 함수 인자라고 부른다:
sin(1) # 삼각함수
[1] 0.841471
log(1) # 자연로그
[1] 0
log10(10) # 지수가 10인 로그
[1] 1
exp(0.5) # e^(1/2)
[1] 1.648721
R에 나온 함수 모두를 기억해야 된다는 걱정은 하지마라. 구글이나 네이버, 다음에서 검색하면 된다. 함수명 앞 글자를 기억하고 있다면 RStudio에서 탭 자동완성 기능을 사용한다.
탭 자동완성이 R 자체 엔진보다 RStudio가 우월성을 갖는 분야로, 자동완성 기능이 함수, 함수 인자, 함수가 전달받을 수 있는 값을 더 쉽게 찾을 수 있게 한다.
명령문 앞에 ?
을 타이핑하고 엔터를 치면 해당 명령어에 대한 도움말 페이지가 열린다. 명령어에 대한 기술과 동작방식에 대한 정보를 제공할 뿐만 아니라, 도움말 페이지 하단으로 스크롤해서 쭉 내리면 해당 명령어 사용법을 시연하는 코드 예제가 나와 있다. 나중에 예제를 통해서 살펴볼 것이다.
다양한 객체 비교하기
R에서 비교 작업도 수행할 수 있다:
1 == 1 # 같음 ("is equal to"로 읽음)
[1] TRUE
1 != 2 # 같지 않음 ("is not equal to"로 읽음)
[1] TRUE
1 < 2 # 보다 작음
[1] TRUE
1 <= 1 # 작거나 같음
[1] TRUE
1 > 0 # 보다 큼
[1] TRUE
1 >= -9 # 같거나 큼
[1] TRUE
변수와 대입
할당 연산자(Assignment Operator), <-
를 사용해서 변수에 값을 저장할 수 있다. 예를 들어:
x <- 1/40
변수에 할당하면, 값을 출력하지 않음에 유의한다. 대신에, 나중에 사용하려고 변수라는 곳에 저장한다. x
변수에는 값 0.025
가 담겨있다:
x
[1] 0.025
좀더 구체적으로, 저장된 값은 부동소수점 수라고 불리는 해당 분수를 소수 근사한 것이다.
RStudio 우측 상단 창에서 Environment
탭을 클릭하면, 변수x
와 값이 저장된 것을 확인할 수 있다. 변수 x
는 숫자가 예상되는 어떤 연산작업에도 숫자자리에 사용될 수 있다:
log(x)
[1] -3.688879
변수가 다시 할당될 수도 있음에 주목한다:
x <- 100
x
변수에 0.025 값이 담겼지만, 현재는 담긴 값이 100
이 된다.
변수에 대입되는 값에는 대입되는 변수도 포함될 수 있다:
x <- x + 1 # 우측 상단 탭에서 RStudio가 x에 대한 정보가 어떻게 바뀌는지 주목한다.
할당하는 우측편은 어떤 적법한 R 표현식도 될 수 있다. 우측편은 대입이 일어나기 전에 완전한 평가가 이루어 진다.
변수명에는 문자, 숫자, 밑줄, 구두점이 포함될 수 있다. 변수명이 숫자로 시작되거나, 공백이 있으면 안된다. 사람마다 긴 변수명에 대해 다른 관례를 사용한다. 다음에 관례가 나와있다.
- 단어.사이.구두점
- 단어_사이_밑줄
- 낙타대문자 : camelCaseToSeparateWords
어떤 관례를 사용하든 여러분 취향이지만, 일관성을 유지하라.
변수에 대입할 때, 할당 =
연산자 사용도 가능하다:
x = 1/40
하지만, R 사용자 사이 그다지 많이 활용되지 않는다. 가장 중요한 것은 사용하는 연산자에 일관성 유지하라. =
보다 <-
을 사용하는 것이 덜 혼동스러운 경우가 있고, 커뮤니티에서 가장 흔히 사용되는 기호다. 그래서 추천하는 것은 <-
이다.
벡터화(Vectorization)
인지해야 되는 마지막 사항은 R은 벡터화
되었다는 사실이다. 변수와 함수는 값으로 벡터를 갖을 수 있다는 의미다. 예를 들어,
1:5
[1] 1 2 3 4 5
2^(1:5)
[1] 2 4 8 16 32
x <- 1:5
2^x
[1] 2 4 8 16 32
놀랍도록 강력한 기능이다; 이점에 대해, 다음 수업에서 좀더 깊이 다룰 예정이다.
환경 설정
R 세션과 상호작용할 때 사용되는 몇가지 유용한 명령어가 있다.
ls
명령어는 전역환경(작업하고 있는 R 세션)에 저장된 모든 변수와 함수 목록을 출력한다:
ls()
[1] "hook_error" "hook_in" "hook_out" "x"
여기서 ls
명령어에 어떤 인자도 전달하지 않았음에 주목한다. 하지만, R에 함수를 호출하려면 괄호는 여전히 전달해야 된다.
ls
만 그 자체로 타이핑하면, R은 해당 함수에 대한 소스코드만 출력한다!
ls
function (name, pos = -1L, envir = as.environment(pos), all.names = FALSE,
pattern, sorted = TRUE)
{
if (!missing(name)) {
pos <- tryCatch(name, error = function(e) e)
if (inherits(pos, "error")) {
name <- substitute(name)
if (!is.character(name))
name <- deparse(name)
warning(gettextf("%s converted to character string",
sQuote(name)), domain = NA)
pos <- name
}
}
all.names <- .Internal(ls(envir, all.names, sorted))
if (!missing(pattern)) {
if ((ll <- length(grep("[", pattern, fixed = TRUE))) &&
ll != length(grep("]", pattern, fixed = TRUE))) {
if (pattern == "[") {
pattern <- "\\["
warning("replaced regular expression pattern '[' by '\\\\['")
}
else if (length(grep("[^\\\\]\\[<-", pattern))) {
pattern <- sub("\\[<-", "\\\\\\[<-", pattern)
warning("replaced '[<-' by '\\\\[<-' in regular expression pattern")
}
}
grep(pattern, all.names, value = TRUE)
}
else all.names
}
<bytecode: 0x7fc99da60190>
<environment: namespace:base>
rm
명령어를 사용해서 더이상 사용할 필요가 없는 객체를 삭제한다:
rm(x)
작업 환경에 너무 많은 객체가 있고, 전부 삭제하고자 한다면, rm
함수에 ls
결과를 전달하면 된다:
rm(list = ls())
상기 예제에서, 명령어 두개를 조합했다. 연산 우선순위처럼, 가장안쪽 괄호 내부에 있는 것이 먼저 평가되고, 쭉 이어서 평가된다.
상기 예제에서, ls
결과가 rm
삭제 명령어 list
인자로 사용되도록 지정했다. 값을 이름으로 인자에 할당할 때, =
연산자를 사용해야만 한다!
대신에 <-
가 사용되면, 의도하지 못한 역효과가 발생되거나, 오류 메시지만 얻게 된다:
rm(list <- ls())
Error in rm(list <- ls()): ... must contain names or character strings
R 팩키지
팩키지를 작성하거나, 누군가 작성한 팩키지를 얻어 R에 함수추가도 가능하다. 현 저작시점에, CRAN(comprehensive R archive network)에는 7,000개 이상 팩키지가 있다. R과 RStudio 모두 팩키지 관리 기능이 있다:
installed.packages()
타이핑하면, 어떤 팩키지가 설치되어 있는지 확인할 수 있다.install.packages("packagename")
타이핑하면, 팩키지를 설치할 수 있다. 여기서packagename
은 팩키지명칭이 된다.update.packages()
타이핑하면, 설치된 팩키지를 갱신할 수 있다.remove.packages("packagename")
타이핑하면, 팩키지를 제거한다.library(packagename)
명령어로 팩키지를 사용할 수 있게 한다.
도전과제 1
다음 프로그램에 나온 각 문장을 실행하게 되면, 각 변수 값에는 무슨 값이 담겨있을까요?
mass <- 47.5
age <- 122
mass <- mass * 2.3
age <- age - 20
도전과제 2
도전과제 1 코드를 실행하고 mass
와 age
를 비교하는 명령어를 작성한다. mass
가 age
보다 큰가요?
도전과제 3
mass
와 age
변수를 삭제해서 작업환경을 정리하세요.
도전과제 4
ggplot2
, plyr
, gapminder
팩키지를 설치하세요.