data.table subset

Published by onesixx on

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
Categories: Reshaping

onesixx

Blog Owner

Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x