I am trying to pass different specific colnames to a data.table inside a loop but I can't figure how to do it or if it possible.
## Simple example
dt <- data.table(one = c(1:4), two = c(5:8), three = c(10:13))
dt[one > 2]
col = "one"
dt[col > 2] ## does not work
## Eventually I would like to do something like this:
lapply(colnames(dt)[1:2], function(x){
dt[x > 2]
})
I thought of working with SDcols
but I don't see how to use it in data.table's i
or j
the way I want.
Is there a way to achieve this ?
CodePudding user response:
Use get()
lapply(colnames(dt)[1:2], function(x){
dt[get(x) > 2]
})
#> [[1]]
#> one two three
#> 1: 3 7 12
#> 2: 4 8 13
#>
#> [[2]]
#> one two three
#> 1: 1 5 10
#> 2: 2 6 11
#> 3: 3 7 12
#> 4: 4 8 13
CodePudding user response:
The following returns a logical matrix.
library(data.table)
dt <- data.table(one = c(1:4), two = c(5:8), three = c(10:13))
col <- "one"
dt[, .SD > 2, .SDcols = col]
#> one
#> [1,] FALSE
#> [2,] FALSE
#> [3,] TRUE
#> [4,] TRUE
Created on 2023-01-17 with reprex v2.0.2
Now coerce the matrix to vector and use it as an index. The simplest way of doing this is with c()
.
dt[c(dt[, .SD > 2, .SDcols = col])]
#> one two three
#> 1: 3 7 12
#> 2: 4 8 13
Created on 2023-01-17 with reprex v2.0.2
Another option is to create the index with sapply
.
dt[dt[, sapply(.SD > 2, all), .SDcols = col], ]
#> one two three
#> 1: 3 7 12
#> 2: 4 8 13
Created on 2023-01-17 with reprex v2.0.2
If you have more than one columns, use apply
.
Note that the data set has changed, the 2nd column now has 1 as its last element.
dt <- data.table(one = 1:4, two = c(5:7, 1), three = 10:13)
cols <- c("one", "two")
dt[dt[, apply(.SD > 2, 1, all), .SDcols = cols], ]
#> one two three
#> 1: 3 7 12
Created on 2023-01-17 with reprex v2.0.2