1. R 프로그래밍 기초 #2
R 프로그래밍 기본 문법
2014.11.13 조대협 http://bcho.tistory.com
2. 조건문과 반복문
• 조건문 if
if(조건){
..
}else{
..
}
ifelse( 조건,TRUE 일때 값,FALSE 일때 값)
ex) isEven<-ifelse(x %% 2==0, “even”, “odd);
• 반복문
명령 예제 설명
for(i in data){..}
for(i in 1:10){
..
}
while(조건){..}
while(i<=10){
..
}
repeat{
..
}
repeat{
..
}
while(TRUE)와 동일
break 반복문 루프를 빠져 나옴
next
현재 반복을 중단하고 다음 반복을 시작
cf. 자바에서 continue;
3. 연산
• 수치 연산
명령 예제 설명
+,-,/,* 사칙연산
n %% m 나머지
n%/%m 몫
n^m 제곱
exp(n) 푒푛
log(x,base=exp(1))
푙표푔푏푎푠푒(푥) 만약 base를 정하지 않으면
푙표푔푒 (푥)
log2(x),log10(x) 푙표푔2 푥 , 푙표푔10(푥)
sin(x),cos(x),tan(x) 각각 삼각함수
4. 연산
• 벡터 연산 (Vectorized Computation)
x<-c(1:5)
> x
[1] 1 2 3 4 5
> x+1
[1] 2 3 4 5 6
> x+x
[1] 2 4 6 8 10
> sum(x)
[1] 15
> mean(x)
[1] 3
> x [1] 1 2 3 4 5
> x == c(2:6)
[1] FALSE FALSE FALSE FALSE FALSE
> x == c(1,3:7)
[1] TRUE FALSE FALSE FALSE FALSE FALSE Warning message: In x == c(1, 3:7) : longer object length is not a multiple of
shorter object length
> x == c(1,3:6) [1] TRUE FALSE FALSE FALSE FALSE
> ifelse(x %%2==0,"even","odd")
[1] "odd" "even" "odd" "even" "odd"
5. NA 값의 처리
• NA : 값이 기록되지 않았거나 관측이 되지 않음 경우. “결측치”라고 함. NULL과 다름
• 데이타에 NA가 포함되어 있으면 모든 계산 결과는 NA가 됨
• 이를 피하기 위해서, R function에는 na.rm=TRUE라는 인자를 넘길 수 있음. (이경우 NA값을 해
당 연산에서 제외함)
NA&TRUE
[1] NA
> NA+1
[1] NA
> NA-1
[1] NA
> sum(c(1:3,NA))
[1] NA
> sum(c(1:3,NA),na.rm=TRUE)
[1] 6
명령 예제 설명
na.fail(object) object에 NA 가 포함되면 fail
na.pass(object) object에 NA가 포함되어 있더라도 pass
na.omit object에 NA가 포함되어 있으면 이를 제외
na.exclude
object에 NA가 포함되어 있으면 이를 제외
omit과 동일하나, exclude는
naresid,napredict를 사용한느 함수에서
NA로 제외한 행을 결과에 추가한다.
6. 함수 정의
• 기본 정의
함수명 <- function(인자…){
..
return(반환값) #반환값이 없으면 생략 가능
}
ex)
add <- function(x,y){
return x+y
}
add(1,2)
• 가변 길이 인자
f<-function(...){
+ args<-list(...)
+ for(a in args){
+ print(a)
+ }
+ }
> f(3,4,5,6,7)
[1] 3
[1] 4
[1] 5
[1] 6
[1] 7
cf. Java argv[]
• 중첩 함수
7. 함수 정의
• 중첩함수
– 함수안에 정의된 함수
– 내부 함수가 외부함수에 정의된 변수를 접근할 수 있다. (Closure)
f<-function(x1){
+ return(function(x2){
+ return (x1+x2)
+ })
+ }
> f(10)
function(x2){
return (x1+x2)
}
<environment: 0x000000000bd9fa20>
>
> g1<-f(10)
> g1(2)
[1] 12
g1은 function(x2)가 저장됨
f<-function(x){
+ g<-function(y){
+ print(x)
+ print(y)
+ }
+ g(10)
+ }
>
> f(99)
[1] 99
[1] 10
함수 g에서 외부함수
에 정의된 변수 x를
참조함
8. 스코프
• 변수의 스코프
– 변수가 정의된 스코프(함수) 내에서만 유효함
– 함수내부에서 전역 변수와 이름이 같은 지역 변수를 사용하면 지역변수가 우선함 (다른 언어와 거의 유사)
rm( 삭제할 객체의 목록, list=삭제할 객체를 나열한 벡터,envir=as.environment(pos) 객체를 삭제할 환경)
rm("f")
> rm(ls())
Error in rm(ls()) : ...는 반드시 이름 또는 문자열을 포함하고 있어야 합니다
> rm(list=ls()) # 현재 환경의 모든 변수/함수 지우기
ls( name, 객체를 나열할 환경의 이름
envir #name 대신 직접 환경을 지정할 경우 사용
)
※ 반환값은 객체이름의 문자열 벡터
• “<<-”
: 상위 스코프에 해당 변수가 있으면 그 변수를 사용, 없으면 상위 스코프에 변수를 생성
f<-function(x){
+ y=x
+ print(y)
+ }
> f(10)
[1] 10
> y
Error: object 'y' not found
f2<-function(x){
+ y<<-x
+ print(y)
+ }
> f2(100)
[1] 100
> y
[1] 100
변수 y가 f2안에서 <<- 로 지정되어, 상위 스코프에서 생성됨
9. 값에 의한 전달 (Pass By Value)
• 함수에 객체를 전달할때 Pass by value 형식으로 전달
– 값을 복사해서 전달 (cf. C언어의 call by value와 동일 개념)
– 그렇다면 실제로 복사할까? 메모리 낭비 (Copy on write/copy on modify)
객체의 불변성 (immutable)
• R에서 객체를 수정하면, 실제로 그 객체가 수정되는 것이 아니라, 새로운 객체를 수정된 값으로
만든 후 지정하는것
※ 자바에서 string 수정과 동일한 개념
> a<-list()
> tracemem(a)
[1] "<0x000000002d90fa68>"
> a$a<-c(3,4,5)
tracemem[0x000000002d90fa68 -> 0x000000002d8f3128]:
> a$a<-c(3,4,2)
tracemem[0x000000002d8f3128 -> 0x000000002d8c3410]:
> a$b<-c(4,5,6)
tracemem[0x000000002d8c3410 -> 0x000000002d0b3050]:
> untracemem(a)
tracemem()이라는 함수를 이용하여, 객체의 메모리 주소 변화를 추적 가능
list에 값을 추가하거나 삭제할때 마다 변수 a의 주소가 바뀌는 것을 확인할 수
있음. 이는 a의 내용이 바뀔때 마다 기존 객체를 수정하는 것이 아니라 새로운
객체로 바뀌는 것임
벡터 연산의 효용성
v <-1:100
for(i in v){
+ v[i]=v[i]+10
+ }
객체의 불변성에 의해서 100번 새로운 벡터를 만듬
※ 실제로 tracemem 해보면 주소가 안바뀐다. 버전이나
OS별로 최적화가 되어 있는듯??
v <-1:100
v <- v+10
이 경우, 벡터 v+10한 객체 하나를 만든후 다시 v에 지정
하기 때문에 위와 달리 효용성이 높다
10. 모듈패턴
• 일반적인 프로그래밍 패턴중의 하나
• 함수를 중첩함수로 구현해서, 외부에서 접근을 못하도록 막는 구현패턴(자바 클래스의 private 메
서드 처럼)
bird<-function(){
fly<-function(){
print("i'm fly")
}
eat<-function(){
print("i'm eating")
}
return(list(fly=fly,eat=eat))
}
> b<-bird()
> b$fly() [1] "i'm fly“
> bird$fly()
Error in bird$fly : object of type 'closure' is not
subsettable
리턴 값으로 명시적으로 함수를 넘겨 주면, 이 경우에는 접근 가능
일반적으로는 내부의 함수를 접근할 수 없음
질문 : R에는 클래스의 개념이 없는가?