R로 데이터 다루기

R에서 dplyr을 이용해 데이터를 추출, 가공하는 방법을 알아봅니다


수강중

4. dplyr과 R 기본함수 비교 (체인과 처리속도)

dplyr 설치

install.packages('dplyr')

dplyr 불러오기

library(dplyr)
Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union

Chain 설명

1 부터 10까지 자연수 더하기

1:10로 1부터 10까지 자연수를 생성한다. sum()으로 수의 합을 구한다.

1:10
sum(1:10)
 [1]  1  2  3  4  5  6  7  8  9 10
[1] 55

sum(1:10)의 같은 결과를 chain을 이용해 구하면 1:10 %>% sum이다.

1:10 %>% sum
[1] 55

Chain의 장점: %>% 뒤에 연달아 조건/함수를 실행 할 수 있다.

복잡한 예시

데이터 프레임을 만들어 df에 저장한다.

df <- data.frame(x = 1:10, y = 10:1)
df
   x  y 
1   1 10
2   2  9
3   3  8
4   4  7
5   5  6
6   6  5
7   7  4
8   8  3
9   9  2
10 10  1

x > 5의 조건에 맞는 행을 뽑아 decreasing= Tsorting을 이용해 내림차순 정렬을 한 후, 4번째 행을 뽑아 y값을 확인한다.

r 기본 코드

df$x > 5
 [1] FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE
df[df$x > 5, ]
   x  y
6   6 5
7   7 4
8   8 3
9   9 2
10 10 1
sort(df[df$x > 5, ]$x, decreasing = T)
[1] 10  9  8  7  6
sort(df[df$x > 5, ]$x, decreasing = T)[4]
[1] 7
df[df$x == 7, ]
  x y
7 7 4

r 기본 한 줄로 표현

df[df$x > 5,][order(df[df$x > 5,]$x, decreasing = T)[4],]
  x y
7 7 4

filter를 사용해서 x > 5 보다 큰 값을 필터링, sort 정렬, desc 함수로 내림차순, slice로 4번째 함수를 뽑는다.

df %>% filter(x > 5) %>% arrange(desc(x)) %>% slice(4)
  x y
1 7 4

가독성이 훨씬 좋다.

변수 이름 바꾸기

df변수는 xy로 바꿔야 하는 경우, r의 기본 코드에서는 일일이 다 고쳐줘야 한다. 하지만 dplyr을 이용한 코드에서는 앞에만 바꿔주면 된다.

xy = df
xy[xy$x > 5,][order(xy[xy$x > 5,]$x, decreasing = T)[4],]
xy %>% filter(x > 5) %>% arrange(desc(x)) %>% slice(4)

체인의 주의점

기본 함수와 체인 활용의 비교 더하기에서 df + 3df %>% +3는 정상적으로 작동하지만, 곱하기에서 df * 3 은 되지만 df %>% *3은 작동하지 않는다.

덧셈 코드

df + 3
df %>% +3

곱셈 코드

df * 3
df %>% *3

데이터프레임 형식에 최적화된 dplyr 함수이기 때문에 모든 상황에서 다 적용한다기보다는 sum(), max()와 같은 함수의 형태에서 사용해야 한다.

일반 함수와 dplyr 함수 속도 비교

hflights 비행시간 데이터 불러오기.

install.packages('hflights')
Updating HTML index of packages in '.Library'
Making 'packages.html' ... done
library(hflights)

dim함수로 데이터의 행과 열의 수를 확인한다.

dim(hflights)
[1] 227496     21

hflights의 첫 번째 두 행의 뽑아 데이터의 전반적인 내용을 확인한다.

hflights[1:2, ]
     Year Month DayofMonth DayOfWeek DepTime ArrTime UniqueCarrier FlightNum
5424 2011 1     1          6         1400    1500    AA            428      
5425 2011 1     2          7         1401    1501    AA            428      
     TailNum ActualElapsedTime ... ArrDelay DepDelay Origin Dest Distance
5424 N576AA  60                ... -10      0        IAH    DFW  224     
5425 N557AA  60                ...  -9      1        IAH    DFW  224     
     TaxiIn TaxiOut Cancelled CancellationCode Diverted
5424 7      13      0                          0       
5425 6       9      0                          0       

일반 함수는 aggregate를 사용하여, dplyr는 chain의 방식으로 월별, 도착지별 평균 도착시간을 구한다.

속도를 비교하기 위해 system.time을 사용한다. 똑같은 결과임에도 불구하고 시간차가 난다. 기본적으로는 일반 r 함수보다 dplyr 함수가 더 빠르다.

일반 r함수의 속도

system.time(aggregate(ArrTime ~ Month + Dest, data = hflights, mean))
   user  system elapsed 
  0.408   0.028   0.440 

dplyr 함수의 속도

system.time(hflights %>% group_by(Month, Dest) %>% summarise(meanArr = mean(ArrTime, na.rm=T)))
   user  system elapsed 
  0.097   0.000   0.100