獨斷論

통계 R 사용설명서 12 - 큰 데이터에서 행과 열을 선택하여 새로운 데이터 생성 본문

과학과 기술/R 통계

통계 R 사용설명서 12 - 큰 데이터에서 행과 열을 선택하여 새로운 데이터 생성

부르칸 2016. 5. 17. 05:18

큰 데이터에서 특정 변수(열)나 특정 관측치(행, observation, subject)만을 선택하여 새로운 데이터를 생성하는 방법에 대해서 알아보자.



변수 선택


행렬이나 데이터프레임에 저장된 데이터 중에 몇개의 변수만 선택하는 방법은 다음과 같다.

일단 아래와 같이 생긴 데이터가 있다고 가정하고


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

 > id <- c('s1', 's2', 's3', 's4', 's5', 's6', 's7', 's8')
 > q1 <- c(10, 3, 5, 8, 4, 7, 3, 6)
 > q2 <- c(7, NA, 4, 5, 9, 10, 1, 9)
 > q3 <- c(9, NA, 8, 9, 9, 4, NA, 8)
 > q4 <- c(8, 6, 10, 4, 5, 2, 9, 10)
 > q5 <- c(3, 6, 8, 3, 5, 4, 6, 8)
 > mydat <- data.frame(id, q1, q2, q3, q4, q5, stringAsFactors = FALSE)
 > mydat
   id q1 q2 q3 q4 q5 stringAsFactors
 1 s1 10  7  9  8  3           FALSE
 2 s2  3 NA NA  6  6           FALSE
 3 s3  5  4  8 10  8           FALSE
 4 s4  8  5  9  4  3           FALSE
 5 s5  4  9  9  5  5           FALSE
 6 s6  7 10  4  2  4           FALSE
 7 s7  3  1 NA  9  6           FALSE
 8 s8  6  9  8 10  8           FALSE


여기서 q2~q5까지 선택하고자 한다면 아래와 같이 하면 된다.


1

2

3

4

5

6

7

8

9

10

11

 > mydat_n <- mydat[ , c(3:6)]
 > mydat_n
   q2 q3 q4 q5
 1  7  9  8  3
 2 NA NA  6  6
 3  4  8 10  8
 4  5  9  4  3
 5  9  9  5  5
 6 10  4  2  4
 7  1 NA  9  6
 8  9  8 10  8


1째 줄에서 mydat[ , c(3:6)]은 모든 행을 선택하고 열은 3에서 6까지 선택하라는 명령어이다.


하지만 자신이 원하는 변수(열)이 몇번째 열인이 기억하는거란 쉽지 않으므로 변수명을 이용하여 원하는 변수만 선택할수 있다. 


1

2

3

4

5

6

7

8

9

10

11

12

 > new_var <- c("q2", "q3", "q4", "q5")
 > mydat_n1 <- mydat[new_var]
 > mydat_n1
   q2 q3 q4 q5
 1  7  9  8  3
 2 NA NA  6  6
 3  4  8 10  8
 4  5  9  4  3
 5  9  9  5  5
 6 10  4  2  4
 7  1 NA  9  6
 8  9  8 10  8


1째 줄에서 new_var에 자신이 원하는 변수명을 입력하였고 이 변수명을 값으로 갖는 새로운 변수 new_var를 이용하여 mydat[new_var]에서 원하는 변수만 선택하였다.


하지만 q2, q3, q4, q5와 같이 앞에 같은 알파벳 변수에 숫자만 바뀌는 형식을 입력하는게 귀찮다면 paste()를 이용해도 된다.

일때 


1

2

3

4

5

6

7

8

9

10

11

12

13

14

 > new_var2 <- paste("q", 2:5, sep="")
 > new_var2
 [1] "q2" "q3" "q4" "q5"
 > mydat_n2 <- mydat[new_var2]
 > mydat_n2
   q2 q3 q4 q5
 1  7  9  8  3
 2 NA NA  6  6
 3  4  8 10  8
 4  5  9  4  3
 5  9  9  5  5
 6 10  4  2  4
 7  1 NA  9  6
 8  9  8 10  8


paste()명령어에서 sep=""의 따옴표 사이에 공백이 없다. sep 옵션은 q와 그 뒤에 붙일 번호 사이에 무엇을 넣을지 결정해주는 것이다.



변수 제거

변수를 제거하기 위해서는 다음과 같이 %in%을 사용하면 된다. %in%은 두 변수 사이에 같은 값이 있는지 없는지 조사해서 같은 값이 있으면 TRUE, 없으면 FALSE를 돌려주는 연산자이다.


1

2

3

4

5

6

7

8

9

10

11

12

 > excld_var <- names(mydat) %in% c("q1", "q4")
 > mydat_n3 <- mydat[!excld_var]
 > mydat_n3
   id q2 q3 q5 stringAsFactors
 1 s1  7  9  3           FALSE
 2 s2 NA NA  6           FALSE
 3 s3  4  8  8           FALSE
 4 s4  5  9  3           FALSE
 5 s5  9  9  5           FALSE
 6 s6 10  4  4           FALSE
 7 s7  1 NA  6           FALSE
 8 s8  9  8  8           FALSE


1째 줄에서 %in%을 이용하여 무엇을 제외할지 선택하여 TRUE와 FALSE를 excld_var에 넣었다.


1

2

 > excld_var
 [1] FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE


2째 줄에서 mydat로부터 excld_var에서 제거하고자 하는 변수를 제거하였다.  !excld_var이라고 하면 TRUE와 FALSE값이 바뀌는 것을 이용하였다.


1

2

 > !excld_var
 [1]  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE


!excld_varmydat[ ]의 인자로 사용하여 mydat[!excld_var]이라고 하면 !excld_var이 TRUE인것만 선택하게 되는 것이다.


이것이 좀 복잡하다면 무식하게 몇번째 열인지 일일이 세면 된다.

q1q4는 2번째 5번째 열에 해당되므로


1

2

3

4

5

6

7

8

9

10

11

 > mydat_n4 <- mydat[c(-2, -5)]
 > mydat_n4
   id q2 q3 q5 stringAsFactors
 1 s1  7  9  3           FALSE
 2 s2 NA NA  6           FALSE
 3 s3  4  8  8           FALSE
 4 s4  5  9  3           FALSE
 5 s5  9  9  5           FALSE
 6 s6 10  4  4           FALSE
 7 s7  1 NA  6           FALSE
 8 s8  9  8  8           FALSE


라고 하면 되는데 역시 데이터가 클 경우 이런건 거의 불가능하다.


만약 원래의 데이터를 저장하지 않고 변수를 지운 데이터만 가지고 있고 싶다면 다음과 같이 하면 된다. 내가 보기에는 이게 더 실질적이고 간단하다.


1

2

3

4

5

6

7

8

9

10

11

12

 > mydat$q1 <- NULL
 > mydat$q4 <- NULL
 > mydat
   id q2 q3 q5 stringAsFactors
 1 s1  7  9  3           FALSE
 2 s2 NA NA  6           FALSE
 3 s3  4  8  8           FALSE
 4 s4  5  9  3           FALSE
 5 s5  9  9  5           FALSE
 6 s6 10  4  4           FALSE
 7 s7  1 NA  6           FALSE
 8 s8  9  8  8           FALSE



관측치(열, observation, subject) 선택


observation에 해당되는 우리말이 관측치라고 하는지 모르겠어서 제목을 이렇게 너저분하게 달아보았다.

여기서는 데이터의 행 전체를 어떻게 선택하는지 알아본다.

우선 다음과 같은 데이터가 있다고 가정하자.


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

 > id <- c(1, 2, 3, 4, 5)
 > country <- c("Korea", "Japan", "China", "Korea", "Mongol")
 > gender <- c("M", "F", "F", "F", "M")
 > age <- c(20, 21, 53, 82, 25)
 > q1 <- c(10, 3, 5, 8, 4)
 > q2 <- c(7, NA, 4, 5, 9)
 > q3 <- c(9, NA, 8, 9, 9)
 > q4 <- c(8, 6, 10, 4, 5)
 > q5 <- c(3, 6, 8, 3, 5)
 > mydat <- data.frame(id, country, gender, age, q1, q2, q3, q4, q5,
 +                     stringAsFactors = FALSE)
 > mydat
   id country gender age q1 q2 q3 q4 q5 stringAsFactors
 1  1   Korea      M  20 10  7  9  8  3           FALSE
 2  2   Japan      F  21  3 NA NA  6  6           FALSE
 3  3   China      F  53  5  4  8 10  8           FALSE
 4  4   Korea      F  82  8  5  9  4  3           FALSE
 5  5  Mongol      M  25  4  9  9  5  5           FALSE


이 중에서  나이가 40이상인 여자만 선택하여 분석하고자 한다면

그냥 눈으로 보고 3번째와 4번째 행에 해당되므로


1

2

3

4

5

 > mydat_n1 <- mydat[c(3,4), ]
 > mydat_n1
   id country gender age q1 q2 q3 q4 q5 stringAsFactors
 3  3   China      F  53  5  4  8 10  8           FALSE
 4  4   Korea      F  82  8  5  9  4  3           FALSE


라고 할수도 있으나 너무 무식하다.  데이터가 큰 경우에는 사용불가!

1

2

3

4

5

 > mydat_n2 <- mydat[which(mydat$gender == "F" & mydat$age >= 40), ]
 > mydat_n2
   id country gender age q1 q2 q3 q4 q5 stringAsFactors
 3  3   China      F  53  5  4  8 10  8           FALSE
 4  4   Korea      F  82  8  5  9  4  3           FALSE


라고 하면 큰 데이터에서도 사용이 가능하다.
만약 which()안에 변수명이 너무 길어서 불편하다면


1

2

3

4

5

6

7

8

9

10

11

 > attach(mydat)
 The following objects are masked _by_ .GlobalEnv:

     age, country, gender, id, q1, q2, q3, q4, q5

 > mydat_n3 <- mydat[which(gender == "F" & age >= 40), ]
 > mydat_n3
   id country gender age q1 q2 q3 q4 q5 stringAsFactors
 3  3   China      F  53  5  4  8 10  8           FALSE
 4  4   Korea      F  82  8  5  9  4  3           FALSE
 > detach(mydat)


하면 된다. 마지막에 detach()를 꼭 넣는것을 잊지 말자.

Comments