data.table subset
Table of contents
DT <- data.table( A=rep(c("a","b","c"),each=2), B=c(1:3), C=sample(6), D=sample(6))
결과가 data.table이 아닌 vector로 나오는 경우,
DT[["A"]] DT[, A] # v column (as vector) DT[, sum(B)] # sum of column v, returned as vector
대부분의 결과는 data.table 형태로,
DT[2,] # 2nd row DT[order(A),] # no need for order(DT$x) DT[, 2] # 2nd column, returns a data.table always DT[, .(B)] # same as above, .() is a shorthand alias to list() DT[, list(B)] # v column (as data.table) DT[, .(sum(B))] # same, but return data.table (column autonamed V1) DT[, .(sv=sum(B))] # same, but column named "sv" DT[, .(B, C*2)] # return two column data.table, v and v*2
Columns
dt <- DT[ , 2:4] mean_row <- dt[ , rowMeans(.SD), .SDcols=names(dt)] mean_col <- dt %>% map_dbl(~ mean(.))
. (dot)
특정 column만 select할때, .( )
를 활용
regression formulas에서 볼수 있었던 (ex. lm(y~., data=DT)
) .
는"all other variables"을 의미하지만,
data.table에서는 "list"를 의미한다.
DT[ , .(B,D)] # identical DT[ , list(B,D)] DT[ , .(E=sum(B))]
Vector를 변수로 사용하여 column 선택
Vectors 를 사용하여 column 선택
DT[ , c("B","D")] # character vector DT[ , c(2,4)] # numeric vector DT[ , c(FALSE,TRUE,FALSE,TRUE)] # logical vector
Pass column name using variable
https://stackoverflow.com/questions/9202413/how-do-you-delete-a-column-by-name-in-data-table
colV <- c("B","D") # c("B","D") c(2,4) c(FALSE,TRUE,FALSE,TRUE) 또는 names(DT)[IdxNum] DT[ , ..colV] DT[ , colV, with=F] DT[ , .SD, .SDcols=colV] DT[ , !..colV] DT[ , (colV):=NULL]
colV <- 2 colV <- c(2,4) #colV <- list(2,4) # Error logical/character/integer DT[ , ..colV] DT[ , colV, with=F] DT[ , .SD, .SDcols=colV]
Subsetting column
.SD만 단순히 사용하면, 원래 값과 같다.
DT DT[ , .SD] # identical DT[ , .SD[ ,c("A","B","C","D")] ] DT[ , .SD, .SDcols=c("A","B","C","D")] DT[ , .SD, .SDcols=A:D] DT[ , .SD, .SDcols=1:4]
A B C D
1: a 1 1 3
2: a 2 6 6
3: b 3 5 4
4: b 1 3 2
5: c 2 4 1
6: c 3 2 5
DT[ , 2] DT[ , .SD, .SDcols=2] cIdx=2; DT[ , ..cIdx] # data.table DT[[2]]; DT[["B"]] # vector
B
1: 1
2: 2
3: 3
4: 1
5: 2
6: 3
DT[B==2,] DT[,.SD,.SDcols=2] DT[,.SD==2,.SDcols=2] DT[,.I[.SD==2],.SDcols=2] DT[DT[ ,.I[.SD==2],.SDcols=2], ] # using only column index # A B C D # 1: a 2 3 1 # 2: c 2 1 5
Self reference
.SD 와 .SDcols (Subset of Data columns)
.SD는 하나의 data.table의 columns을 각각 sub-data.table로 나누어 self reference할수 있게 해준다.
A column와 B column을 paste하는 것을 .SD를 활용하여 같은 결과를 구현할수 있다.
str_c(DT$A, DT$B, sep="") DT[ , .SD[ , str_c(A,B,sep="")]] # identical
[1] "a1" "a2" "b3" "b1" "c2" "c3
ROW
한 column에 조건을 사용하여 row subsetting
DT[B==3,] # A B C D # 1: b 3 5 4 # 2: c 3 2 5 limit <- 3 DT[B==limit,] colNm <- c("B") DT[get(colNm)==3,]
sub-data.table의 ridx를 활용하여 원하는 row만 뽑아올수 있다. (각 그룹의 B열에서 max값을 갖는 row를 뽑아옴)
DT[, .SD[which.max(B)], by=A]
A B C D
1: a 2 4 5
2: b 3 3 3
3: c 3 5 1
DT[, .(max(B)), by=A] DT[, lapply(.SD, max), .SDcols=c('B'), by=A] DT[, lapply(.SD, function(x){B=max(x)}), .SDcols=c('B'), by=A]
A B
1: a 2
2: b 3
3: c 3