통계R 자료구조와 연산
Vector, Matrix, Dataframe, Array, List 의 연산과 데이터 접근법 등을 알아본다.
Vector형
- 1차원 데이터를 저장할 때 주로 사용
- 데이터 유형은 동일해야 한다.
> x = c(1,2,"3",TRUE) # 선언하게 되면 [1] "1" "2" "3" "TRUE" #모두 Character로 변경됨 > x = c(1,2,TRUE) # 선언하게 되면 [1] 1 2 1 "TRUE" #모두 numeric변경됨
- 생성방법
> x = c(1,2) # c로 선언
- 접근방법
> x = c(1,2) # c로 선언 또는 1:2 형태로 선언도 가능하다. > x[1] # 첫번째 데이터
- 연산
# 자료가 부족한 Vector는 반복해서 채워서 연산을 한다. RECYCLING RULE > x = c(1,2,3,4) > y = c(1,2) > x+y [1] 2 4 4 6
Matrix형
- 2차원 데이터를 저장할 때 주로 사용 ( 2차원은 Dataframe 도 있음)
- 저장되는 모든 데이터 유형은 동일 해야 함
- 생성방법
- matrix 함수 적용
> x = 1:6 > mx = matrix(x, nrow=2,ncol=3,byrow=F) # 2by3 matrix , byrow가 false이면 세로기준으로 채워간다. [,1] [,2] [,3] [1,] 1 3 5 [2,] 2 4 6
- 여러개의 vector를 결합해서 묶는 방법
> x = 1:4 > y = 5:8 > my = cbind(x,y) x y [1,] 1 5 [2,] 2 6 [3,] 3 7 [4,] 4 8
- 빈(Empty) 메트릭스 선언
> em = matrix(,nrow=2,ncol=3) > em [,1] [,2] [,3] [1,] NA NA NA [2,] NA NA NA > for(i in 1:3) { em[,i] = c(2,2) } > em [,1] [,2] [,3] [1,] 2 2 2 [2,] 2 2 2
- matrix 함수 적용
- 접근방법
> mx[1,3] # 1,3번째 [1] 5 > mx[,2] # 2번째 컬럼 열전부 [1] 3 4 > mx[1:4] # 첫번째 데이터부터 세로기준으로 4번째 데이터 까지 [1] 1 2 3 4
- 연산
> xm = matrix(1:6,nrow=2,ncol=3 ) > ym = matrix(10:15, nrow=2, ncol=3) # row,col이 다른경우 연산은 불가 , Error in mx + ym : non-conformable arrays > ym+xm [,1] [,2] [,3] [1,] 11 15 19 [2,] 13 17 21 > ym/em [,1] [,2] [,3] [1,] 5.0 6.0 7.0 [2,] 5.5 6.5 7.5 > xm & ym #모두 숫자형이라서 0이 없으면 True 연산됨 [,1] [,2] [,3] [1,] TRUE TRUE TRUE [2,] TRUE TRUE TRUE # 이경우는 첫번째 원소간의 연산결과만을 출력한다. > xm && ym [1] TRUE
- 행과열에 이름붙이기
> rownames(ym) NULL > colnames(ym) NULL > rownames(ym) = c("r1","r2") > ym [,1] [,2] [,3] r1 10 12 14 r2 11 13 15 > colnames(ym) = c("c1","c2") # 행이나 열의 수에 안맞게 naming을 하면 에러 발생 Error in dimnames(x) # naming 이후는 행이나 열이름으로 접근이 가능하다 ex) ym["r1",]
DataFrame
- 2차원 데이터를 저장할 때 주로 사용
- 저장되는 모든 데이터의 컬럼 유형만 같으면 됨
-
생성방법
- data.frame 함수 적용
# 주의 cbind(A,B) 또는 rbind(A,B)로 묶으면 Matrix형으로 만들어지게됨 # data.frame은 열기준으로 생성됨 > A = c("AAA","BBB","CCC") > B = c(1,2,3) > df = data.frame(A,B) A B 1 AAA 1 2 BBB 2 3 CCC 3 > class(df[2,]) [1] "data.frame" > class(df[,2]) [1] "numeric"
- 빈 dataframe 선언 및 값채우기
> df = data.frame(matrix(ncol=3)) > df X1 X2 X3 1 NA NA NA > x = c(1,3,5) # 동일 데이터 형만을 채우게 됨 > for ( i in 1:3 ) { df[i,] = x } > df X1 X2 X3 1 1 3 5 2 1 3 5 3 1 3 5 # df를 세로기준으로 채우기 위해 df[,1] = x 하면 에러가 발생한다. # 가로기준으로만 채워 나갈 수 있다.
# 세로 기준으로 값을 채워나가는 예제 > df = data.frame(matrix(nrow=3)) > df matrix.nrow...3. 1 NA 2 NA 3 NA > x = c(1,3,4) > y = c("A","B","C") > z = c(T,F,T) > df[,1] = x > df[,2] = y > df[,3] = z > df matrix.nrow...3. V2 V3 1 1 A TRUE 2 3 B FALSE 3 4 C TRUE
- 행 또는 열 삭제
> df[,-1] # 첫번째 열 삭제 > df[,c(2,3)] # 2,3번째 열선택 > df[-1,] # 첫째행 삭제
- 행 또는 열 추가
# 컬럼추가 - 마지막 컬럼보다 2이상 큰 인덱스로 추가를 하면 오류 발생 > A = c("A","B","C") > B = c(1,2,3) > df = data.frame(A,B) # 아래 추가 말고 존재하는 컬럼명이나 컬럼인덱스로 지정하게 되면 값이 Replace가 됨 ## 방법 1 - 컬럼명을 주지 않는 방법 (자동으로 컬럼명 부여) > df[,3] = c(1,2,3) # 인덱스를 주어 추가 , df[,10] 와 같이 만약 인덱스가 최대인덱스 + 1 보다 크면 에러 발생 new w columns would leave holes after existing columns ## 방법 2 - 컬명명을 직접 주는 방법 > df[,'addcol'] = c(1,2,3) ## 방법 3 - 컬명명을 직접 주는 방법 > df$addcol = c(1,2,3) ## 방법 4 - transform(dataframe, variable='') 함수 사용 , 여러개 동시 추가하는 경우 주로 사용 > df = transform( df, addcol = c(1,2,3) ) # 행추가 - 행추가는 마지막 row 이상으로 지정하더라도, 자동으로 늘어고 중간값은 NA로 채워짐 > df[4,] = c("A",2) # 추가하고자 하는 열에 데이터 타입을 맞춰서 추가 > df[100,] = c("A",2) # 마지막 행을 넘어서 추가하면 중간값은 NA로 채워짐
- 빈행 또는 빈열 추가
> df[4,] = NA # 마지막 행에 빈행을 추가한다. > df[3] = NA # 오른쪽 빈컬럼을 추가한다. > df['a'] = NA # a라는 컬럼에 빈컬럼을 추가한다.
-
Dataframe 끼리의 결합 : rbind, cbind, merge
-
접근방법
> df A B 1 AAA 1 2 BBB 2 3 CCC 3 #행렬을 방법으로 > df[1,1] # 1,1번째 - class(df[1,1]) : character > df[1,3] # 1,3번째 - class(df[1,2]) : numeric > df[,2] # 2번째 컬럼전부 - class(df[,2]) : numeric > df[1] # 1번째 컬럼전부 - class( df[1] ) data.frame의 컬럼 서브셋 > df[1:2,] # 1~2번째 ,2행도 포함 열전부 - class( df[1:2,] ) : data.frame 의 서브셋 > df[1:2,1] # 1~2번째,2행도 포함 1열만 - class( df[1:2,1] ) : character > df[1:2] # 1~2번째 컬럼전부 - class( df[1:2] ) : data.frame #컬럼명지정 ------------------------------------------------------- ## 아래의 3가지는 모두 컬럼데이터 이며, class(df$A) : "character"로 동일함 > df$A [1] "AAA" "BBB" "CCC" > df[,1] [1] "AAA" "BBB" "CCC" > df[[1]] [1] "AAA" "BBB" "CCC" ## 아래는 dataframe의 부분 서브 dataframe을 지정하는 방법이다. class(df[1]) : "data.frame"가 리턴됨 > df[1] # df['A'] 와 동일 A 1 AAA 2 BBB 3 CCC
-
연산
# dataframe 연산규칙은 동일사이즈(행,열) 끼리만 가능 # 동일한 column은 데이타 타입이 동일해야 연산이 가능 > A = c(100,100,100) > B = c(1,2,3) > df1 = data.frame(A,B) > X = c(2,2,2) > Y = c(10,20,30) > df2 = data.frame(X,Y) > df1+df2
# 다른 데이터 타입인경우 column은 데이타 타입이 동일해야 연산이 가능 > A = c("A","B","C") > B = c(1,2,3) > df1 = data.frame(A,B) > X = c(1,3,4) > Y = c(10,20,30) > df2 = data.frame(X,Y) > df1$B + df2$Y # 가능 > df1$A & df2$B # 불가능 A,B가 &에 맞지 않는 데이터 타입
-
컬럼명 바꾸기
> names(df2) # df2에서 컬럼명 보기 [1] "X" "Y" # 방법 1 : names() 함수를 이용하면 전체를 변경할 수 있음 > names(df2) = c("ABC","DEF") > df2 ABC DEF 1 1 10 2 3 20 3 4 30 # 방법 2 : plyr 패키지의 rename() 함수사용하면 컬럼별 1대1로 변경 가능 , > library(plyr) > df2 = rename(df2, c("ABC"="ABC만변경") ) > df2 ABC만변경 DEF 1 1 10 2 3 20 3 4 30
- data.frame 함수 적용
list 형
- 서로다른 데이터 타입을 갖는 벡터들을 저장
- 길이나 데이터 타입이 달라도 됨
- list(키 = 값, 키 = 값)
- 리스트를 대상으로 하는 apply family에는 lapply(), rapply() 두가지가 있다.
- lapply()는 키별(컬럼별)로 함수가 적용, rapply는 구성요소 하나하나에 함수를 적용
-
생성방법
-
리스트 함수로 정의
# 리스트로 선언 > x = c(2,3,4,5) > y = c(TRUE,FALSE) # 키는 인용부 있고 없고 동일, 마지막에 키가 없어도 됨 # 키를 지정하지 않으면, [[4]] 와 같이 자동으로 번호를 지정 해줌 > lz = list('num'=x, ox=y, etc="가나다", c(1,2,3)) > lz $num [1] 2 3 4 5 $ox [1] TRUE FALSE $etc [1] "가나다" [[4]] [1] 1 2 3 > class(lz) [1] "list" > class(lz$num) [1] "numeric"
-
빈 리스트 만들어 데이터 채우기
#리스트는 데이터를 추가할때 행과 열이 자동으로 확장됨 > lt = vector(mode='list') > for( i in 1:5) { lt[[i]] = 1:i } [[1]] [1] 1 [[2]] [1] 1 2 [[3]] [1] 1 2 3 [[4]] [1] 1 2 3 4 [[5]] [1] 1 2 3 4 5
-
-
접근방법
# 해당컬럼 접근방법 > lz$num # 키 로접근 - class(lz$num) : numeric [1] 2 3 4 5 # 키 로접근 - 이경우는 리턴값이 list 이다, class(lz['num']) : list # 실제로는 lz['num']$num 이 정확하다, 즉 리스트에서 num만 슬라이싱 해서 부분리스트를 가져온 것 > lz['num'] $num [1] 2 3 4 5 > lz[[1]] # 키없이 접근- class(lz[[1]]) : numeric [1] 2 3 4 5 # 데이터 접근방법 , 1첫째에서 2번째 열해당 가져오기 > lz$num[2] # 키 로접근 [1] 3 > lz['num']$num[2] # 키 로접근 [1] 3 > lz[[1]][2] # 키없이 접근 [1] 3 # 대괄호 1나와 2개의 차이점 - 대괄호 1개는 lz['num'] 과 동일것임 > lz[1] # 대괄호 1개 인것은 첫번째 인덱스를 가진 sublist(부분리스트)를 지정한것 , class(lz[1]) : list $num [1] 2 3 4 5 > lz[[1]] # 대괄호 2개 인것은 첫번째의 vector를 가져온 것임 , class(lz[[1]]) : numeric [1] 2 3 4 5
-
연산
# list 연산규칙은 동일사이즈(행,열) 끼리도 연산 안됨 # 동일한 column은 데이타 타입이 동일해도 연산 안됨 # 리스트 끼리의 연산은 불가 > A = c(100,100,100) > B = c(1,2,3) > dl1 = list(A,B) > X = c(2,2,2) > Y = c(10,20,30) > dl2 = list(X,Y) > dl1+dl2 Error in df1 + df2 : non-numeric argument to binary operator
# column 만 추출한 연산은 가능 > A = c(100,100,100) > B = c(1,2) > dl1 = list(A,B) > X = c(2,2,2) > Y = c(10,20) > dl2 = list(X,Y) > dl1[[1]]+dl2[[1]] # 연산가능 > dl1[[1]]+dl2[[2]] # 연산가능 dl1[[1]] 길이와 dl1[[2]]의 길이가 다름 Recyling rule 적용됨 > dl1[1]+dl2[1] # 연산불가능, 대괄호 하나는 리스트 형태이기 때문에.
-
Array 형
- 다차원 형태의 Matrix 임
- Matrix의 확장
-
생성방법
> array(1:100, dim=c(2,3,3)) , , 1 [,1] [,2] [,3] [1,] 1 3 5 [2,] 2 4 6 , , 2 [,1] [,2] [,3] [1,] 7 9 11 [2,] 8 10 12 , , 3 [,1] [,2] [,3] [1,] 13 15 17 [2,] 14 16 18
- 선택방법
> x[,,1] # 1번째 메트릭스 [,1] [,2] [,3] [1,] 1 3 5 [2,] 2 4 6 > x[,,2] # 2번째 메트릭스 [,1] [,2] [,3] [1,] 7 9 11 [2,] 8 10 12 > x[1,,] # 각 매트릭스에서 1첫째 행을 모두선택해서 세로로 채운 매트릭스 [,1] [,2] [,3] [1,] 1 7 13 [2,] 3 9 15 [3,] 5 11 17 > x[,2,] # 각 매트릭스에서 2번째 컬럼을 모두 선택해서 세로로 채운 매트릭스 [,1] [,2] [,3] [1,] 3 9 15 [2,] 4 10 16
댓글남기기