Home > Mobile >  lapply using colnames with data.table
lapply using colnames with data.table

Time:01-17

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

  • Related