【发布时间】:2018-09-18 18:05:12
【问题描述】:
我正在 R 中编写一个估计程序,循环遍历用户声明的 data.frame 中的变量名称列表。我试图避免要求用户引用变量以使他们的生活更轻松(目标是将其上传到 CRAN,因此我们非常关心用户体验)。
为了防止 R 尝试计算变量名,我构造了函数 alt(),它类似于 c() 和 list() 的替代方法,但不计算元素。
我的问题是如何优雅地取消alt() 函数,让用户可以少学习一个函数。这是一个简单的 MWE,希望能说明问题:
## Construct non-evaluating list function
alt <- function(...) {
alt <- as.list(substitute(list(...)))
return(alt[-1])
}
## Construct function that enquotes non-evaluated vectors
## contained in 'alt()'. Perhaps enquoting variable names
## is unavoidable because the data set is stored as a
## data.frame, but at least the user will not have to do it.
restring <- function(vector) {
vector <- deparse(vector)
if (substr(vector, start = 1, stop = 2) == "c(") {
vector <- substr(vector, 3, nchar(vector) - 1)
vector <- strsplit(vector, ", ")[[1]]
}
return(vector)
}
## Example of a function that loops over the list above
## for a given data set. The function simply prints out
## the columns declared in each element of 'alt()'.
test <- function(data, vlist) {
for (i in 1:length(vlist)) {
print(paste0("Data set ", i, ":"))
print(data[, restring(vlist[[i]])])
}
}
## Construct example data
N <- 4
df <- data.frame(x1 = c(1, 2),
x2 = c(3, 4))
## Example of user-declared list of variables to loop over
vlist <- alt(x1, c(x1, x2))
## Output from running this example
> test(df, vlist)
[1] "Data set 1:"
[1] 1 2
[1] "Data set 2:"
x1 x2
1 1 3
2 2 4
用户也可以声明
test(df, alt(x1, c(x1, x2)))
但如果我不必要求用户使用不同的函数来声明这些变量列表,那就太好了。如果它可以使用标准 R 函数工作,例如
test(df, list(x1, c(x1, x2)))
那太好了,但除了使用 deparse(substitute()) 执行一些笨拙的字符串操作之外,我找不到其他方法,类似于 restring() 函数(不确定 CRAN 对此有何感受)。
对于这个非标准评估问题的任何想法都将不胜感激。另外,如果alt() 使用起来很容易以至于不值得删除,那也很高兴知道。
【问题讨论】:
-
如果您希望他们能够在主要的
test()函数调用之外使用符号,例如vlist <- alt(x1, c(x1, x2)),那么您确实需要保留alt()。当您调用test()时,您可以进行一些非标准评估,但是当您真正想要强制评估时,这将无济于事。做这些事情似乎是个好主意,但是当用户编写自己的函数来包装这些函数时,事情会变得非常混乱。如果他们只需要学习一个全新的范例,我不确定避免引用是否会使事情变得更容易。 -
公式是人们捕捉符号而不是评估它们的另一种方式。例如
vlist <- list(~x1, ~x1+x2) -
@MrFlick 非常感谢您的回复。我没有考虑过使用公式。但是你提到在
test()之外使用符号真的很重要,而且是我没有考虑过的。鉴于此,我认为我确实必须坚持使用alt()函数。同样,用户体验是我们关心的问题,如果主函数可以用于更复杂的设置,那么用户学习一个简单的辅助函数来列出变量的成本似乎是值得的。再次感谢您指出这一点!
标签: r list function dataframe evaluation