data_frame
dplyr은 data.frame을 더 편리하게 사용할 수 있도록 변형된 형태의 data.frame을 제공한다
초창기부터 제공했던 tbl_df
을 이용하면 화면에 맞게 행과 열의 수를 제한해서 볼 수 있고
dplyr과 관련된 추가적인 정보(group_by
정보, column의 type, source정보 등)를 제공한다
이후에 추가된 data_frame
은 tbl_df와 data.frame을 기반으로 하여 data.frame을 더욱 편리하게 사용할 수 있도록 여러가지 기능을 제공한다
dplyr의 기능과 궁합이 잘 맞는 데이터 형태이기 때문에 차이점을 명확하게 알고 쓴다면 도움이 많이 될 것 같다
아래 내용은 dplyr 패키지 내부에 있는 data_frames
문서를 정리하고 일부 내용을 추가했다
R에서는 dplyr 패키지를 불러온 후에 vignette('data_frames')
명령어로 문서를 볼 수 있으며
CRAN 페이지에서도 문서를 확인할 수 있다
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
data.frame과의 차이점
data.frame은 stringsAsFactors = FALSE
를 해주지 않으면 문자열을 factor로 가져간다
data.frame(month = month.abb) %>% sapply(class)
## month
## "factor"
data_frame은 입력한 데이터의 type을 변경하지 않는다
data_frame(month = month.abb) %>% sapply(class)
## month
## "character"
list를 값으로 가지는 column을 쉽게 생성할 수 있다
list_col = data_frame(index = 1:3,
rnorm = list(rnorm(10, 0, 1),
rnorm(5, 0, 1),
rnorm(7, 0, 1))
)
list_col[1,2][[1]]
## [[1]]
## [1] -0.21884373 -0.83728231 0.74070271 -0.01440668 1.92528622
## [6] 0.64657433 1.53596809 0.37297701 0.75368773 1.26919784
이 경우 rnorm column은 list의 형태로 출력되기 때문에
sapply 함수를 이용하면 mutate와 함께 자료를 정리할 수 있다
list_col %>%
mutate(mean = sapply(rnorm, function(x) mean(x)))
## Source: local data frame [3 x 3]
##
## index rnorm mean
## (int) (chr) (dbl)
## 1 1 <dbl[10]> 0.6173861
## 2 2 <dbl[5]> -0.2303840
## 3 3 <dbl[7]> -0.2237431
data_frame은 변수의 이름을 변경하지 않는다
# space.variable
data.frame('space variable' = 1)
## space.variable
## 1 1
# space variable
data_frame('space variable' = 1)
## Source: local data frame [1 x 1]
##
## space variable
## (dbl)
## 1 1
값을 계산할 때 느긋(lazy)하게 순차적으로 진행한다
다시 말하자면, dplyr의 mutate 함수를 사용하는 것처럼 data_frame을 생성할 수 있다
# Error
data.frame(x = 1:5, y = 3*x)
Error in data.frame(x = 1:5, y = 3 * x) : object 'x' not found
data_frame(x = 1:5, y = 3*x)
## Source: local data frame [5 x 2]
##
## x y
## (int) (dbl)
## 1 1 3
## 2 2 6
## 3 3 9
## 4 4 12
## 5 5 15
기타 특이사항들
data_frame은 row.names()
를 사용하지 않는다
tidy data의 관점에서 변수는 attribute로 관리하지 않고 테이블 안에서 변수로 직접 관리한다
data_frame에서 벡터의 재사용은 길이 1의 벡터로만 한정한다
큰 단위의 벡터에서 벡터 재사용은 버그의 빈번하게 발생시킨다
아래 예제에서 보면 x와 y 벡터는 길이가 다르지만
data.frame에서는 y를 다시 사용하는 방식으로 길이를 맞춰서 data.frame을 생성한다
data_frame은 그러한 벡터 재사용을 허용하지 않는다
data.frame(x = 1:4, y = 1:2)
## x y
## 1 1 1
## 2 2 2
## 3 3 1
## 4 4 2
# Error
data_frame(x = 1:4, y = 1:2)
Error in data_frame_(lazyeval::lazy_dots(...)) :
arguments imply differing number of rows: 4, 2
data_frame은 tbl_df 클래스를 추가시킨다
따라서 기본적으로는 데이터를 호출했을 때 데이터의 일부만 보이게 된다
print(data_frame, n = 100)
등의 함수로 원하는 만큼의 데이터를 볼 수 있다
tbl_df 클래스로 인해서 [ ]의 동작도 달라진다
기존 data.frame에서는 해당 열을 벡터로 바꾸어서 출력하는 반면에
data_frame에서는 형태를 변경하지 않는다
iris_head = head(iris)
iris_df = tbl_df(iris_head)
iris_head[,'Species']
## [1] setosa setosa setosa setosa setosa setosa
## Levels: setosa versicolor virginica
iris_df[,'Species']
## Source: local data frame [6 x 1]
##
## Species
## (fctr)
## 1 setosa
## 2 setosa
## 3 setosa
## 4 setosa
## 5 setosa
## 6 setosa
data_frame으로 변경하려면 as_data_frame()
함수를 사용하면 된다
as.data.frame()
보다 훨씬 빠르다
as_data_frame(iris)
## Source: local data frame [150 x 5]
##
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## (dbl) (dbl) (dbl) (dbl) (fctr)
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
## 7 4.6 3.4 1.4 0.3 setosa
## 8 5.0 3.4 1.5 0.2 setosa
## 9 4.4 2.9 1.4 0.2 setosa
## 10 4.9 3.1 1.5 0.1 setosa
## .. ... ... ... ... ...