# data.table subset

```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: R Reshaping

Blog Owner

Subscribe
Notify of