首页 > 解决方案 > 将不带引号的函数参数传递给 data.table 中的 i

问题描述

我正在为我的同事创建一个函数来轻松分析一些预先指定的数据集。我希望他们能够将“i”参数传递给选择行。为了使它更健壮,我希望能够使用或不使用引号来传递这个参数。

这是一个使用引号的示例……

x <- data.table(x = c(1,1,1,2,2,2,3,3,3), 
  sex = c("M", "M", "F","M", "F","M", "F","M", "F"))
test.function <- function(my.dt, ...){
  where <- parse(text = paste0(list(...))) 
  my.dt <- my.dt[eval(where), ]
  return(my.dt)
}
tmp <- test.function(x, 'x==3 | sex=="F"')
head(tmp) 

如果我删除引号,它会说“找不到对象'sex'”......

x <- data.table(x = c(1,1,1,2,2,2,3,3,3), 
  sex = c("M", "M", "F","M", "F","M", "F","M", "F"))
test.function <- function(my.dt, ...){
  where <- parse(text = paste0(list(...))) 
  my.dt <- my.dt[eval(where), ]
  return(my.dt)
}
tmp <- test.function(x, x==3 | sex=="F")
head(tmp)

除了上述之外,我还多次尝试使用引号、替换和 rlang 失败:比如这个失败的示例……</p>

x <- data.table(x = c(1,1,1,2,2,2,3,3,3), 
                sex = c("M", "M", "F","M", "F","M", "F","M", "F"))
test.function <- function(my.dt, ...){
  where <- rlang::quos(...)
  my.dt <- my.dt[!!where, ]
  return(my.dt)
}
tmp <- test.function(x, 'x==3 | sex=="F"')
head(tmp, 10)

除了解决方案的任何想法之外,如果有人能将我指向一个简单的在线资源以了解符号/表达式/引号/等,我将不胜感激。当我深入研究这个问题时,我意识到我在理解 R 的工作原理方面存在一些严重的差距。

顺便说一句,我已经阅读了以下内容,但都无法帮助我:Passing function argument to data.table iPassing multiple arguments to data.table inside a function

标签: rfunctiondata.tableparameter-passing

解决方案


可能还有其他(更好的)选项,但您可以将其包装tryCatchbquote用于未引用的参数

test.function <- function(my.dt, ...){
    where <- tryCatch(parse(text = paste0(list(...))),  error = function (e) parse(text = paste0(list(bquote(...)))))
    my.dt <- my.dt[eval(where), ]
    return(my.dt)
  }

tmp <- test.function(x, 'x==3 | sex=="F"')
head(tmp) 
   x sex
1: 1   F
2: 2   F
3: 3   F
4: 3   M
5: 3   F

tmp <- test.function(x, x==3 | sex=='F')
head(tmp)
   x sex
1: 1   F
2: 2   F
3: 3   F
4: 3   M
5: 3   F

推荐阅读