Evaluating both column name and the target value within `j` expression within `data.table`

后端 未结 1 984
自闭症患者
自闭症患者 2020-11-27 08:00

Consider

target <- \"vs\"
value <- 1

library(data.table)
dt <- as.data.table(head(mtcars))

So I\'m trying to pass both column nam

相关标签:
1条回答
  • 2020-11-27 08:35

    Here is one possible alternative.

    target <- "vs"
    value <- 1
    dt <- as.data.table(head(mtcars))
    

    In terms of code it's not necessarily simpler, but we can set up an unevaluated call cl defined outside the scope of dt which is to be evaluated inside the data table's environment.

    cl <- substitute(
        x == y, 
        list(x = as.name(target), y = value)
    )
    

    substitute() might be necessary for longer expressions. But in this case, call() would shorten the code and create the same cl result. And so cl could also be

    cl <- call("==", as.name(target), value)
    

    Now we can evaluate cl inside dt. On your example this seems to work fine.

    dt[, NEWCOL := sum(eval(cl)), by = am][]
    #     mpg cyl disp  hp drat    wt  qsec vs am gear carb NEWCOL
    # 1: 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4      1
    # 2: 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4      1
    # 3: 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1      1
    # 4: 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1      2
    # 5: 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2      2
    # 6: 18.1   6  225 105 2.76 3.460 20.22  1  0    3    1      2
    

    After thinking about this for a minute, I'm not sure value needed to be substituted, and hence the following also works. But as David notes, the first approach is more time efficient.

    dt[, eval(as.name(target)) == value]
    # [1] FALSE FALSE  TRUE  TRUE FALSE  TRUE
    
    0 讨论(0)
提交回复
热议问题