如何评估字符串以过滤R data.table?

Ale*_*exP 3 r data.table

我希望在将一串过滤条件传递给data.table时提供一些帮助.我已经尝试了解析和评估的所有方式,似乎无法弄明白

我尝试使用iris数据集重新创建一个示例:

iris <- data.table(iris)

vars <- 'setosa'                    
filter <- 'Species == vars & Petal.Length >= 4'

data <- iris[filter, 
             list(sep.len.tot = sum(Sepal.Length), sep.width.total = sum(Sepal.Width)), 
             by = 'Species']
Run Code Online (Sandbox Code Playgroud)

因此,过滤器字符串中包含一个变量变量(基于循环而变化).我正在尝试根据过滤字符串过滤数据.

是否有一个data.table特定的方法来评估字符串?

希望有道理!

Mik*_* H. 8

我认为eval(parse(text()))会有效,你只需要一些修改.试试这个:

library(data.table)
iris <- data.table(iris)

#Updated so it will have quotes in your string
vars <- '\"setosa\"'  
#Update so you can change your vars
filter <- paste0('Species==',vars,'& Petal.Length >= 4')

res <- iris[eval(parse(text=filter)), list(
  sep.len.tot = sum(Sepal.Length)
  , sep.width.total = sum(Sepal.Width)
), by = 'Species']
Run Code Online (Sandbox Code Playgroud)

一些注意事项:我更新了你vars的字符串中会有引号,所以它会正常运行,我也会更新,filter所以你可以动态更改vars.

最后,为了解释的目的,得到的df是空白的(因为没有setosa物种有Petal.Length> = 4.所以为了看到这个工作,我们可以删除最后一个条件.

filter <- paste0('Species==',vars)
res2 <- iris[eval(parse(text=filter)), list(
  sep.len.tot = sum(Sepal.Length)
  , sep.width.total = sum(Sepal.Width)
), by = 'Species']

res2
   Species sep.len.tot sep.width.total
1:  setosa       250.3           171.4
Run Code Online (Sandbox Code Playgroud)

编辑:Per @ Frank的评论如下,更简洁的方法是将整个事物写成表达式:

filter <- substitute(Species == vars, list(vars = "setosa"))

res <- iris[eval(filter), list(
  sep.len.tot = sum(Sepal.Length)
  , sep.width.total = sum(Sepal.Width)
), by = 'Species']
Run Code Online (Sandbox Code Playgroud)

  • 我想这是更清洁的表达代替,而不是粘贴和解析.我的意思是`filter < - substitute(Species == vars&Petal.Length> = 4,list(vars ="setosa")); 虹膜[EVAL(过滤器)]` (2认同)