Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subsetting a data.table using logical function by calling its string name

Tags:

r

data.table

I have a function containing a logical expression to subset the rows of a data.table. I want to call this function by its name given by a character string and a vector of column names representing the function arguments as well (as similar to using do.call). However, I have no clue how to approach that intention.

In a simple, reproducible example:

#function with logical return value
myfunc <- function(mpg, cyl) {
  mpg/cyl > 7
}

#name of function
funcname <- "myfunc"

#vector of column names, corresponding to the function parameters
cols <- c("mpg", "cyl")

#data.table to be subsetted
dt <- setDT(copy(mtcars))

What I am looking for is a function to pass the variables dt, funcname and cols in order to obtain the following result as it is identical to dt[mpg/cyl > 7, ]:

#desired function
subsetfunc(dt, funcname, cols)

    mpg cyl disp  hp drat    wt  qsec vs am gear carb
1: 32.4   4 78.7  66 4.08 2.200 19.47  1  1    4    1
2: 30.4   4 75.7  52 4.93 1.615 18.52  1  1    4    2
3: 33.9   4 71.1  65 4.22 1.835 19.90  1  1    4    1
4: 30.4   4 95.1 113 3.77 1.513 16.90  1  1    5    2
like image 212
parterre Avatar asked Feb 13 '26 11:02

parterre


1 Answers

In case you are interested in exploring the env parameter in data.table version 1.14.3, here is an alternative approach:

subsetfunc <- function(dt,funcname,cols) {
  dt[f(c1, c2), env = list(f=funcname, c1=cols[1], c2=cols[2])]
}

subsetfunc(dt,funcname,cols)

Output:

    mpg cyl disp  hp drat    wt  qsec vs am gear carb
1: 32.4   4 78.7  66 4.08 2.200 19.47  1  1    4    1
2: 30.4   4 75.7  52 4.93 1.615 18.52  1  1    4    2
3: 33.9   4 71.1  65 4.22 1.835 19.90  1  1    4    1
4: 30.4   4 95.1 113 3.77 1.513 16.90  1  1    5    2
like image 119
langtang Avatar answered Feb 15 '26 12:02

langtang



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!