如何将用户定义函数的参数传递为data.table中的列名称?

问题描述:

如何传递参数作为函数中data.table的列名称? 例如,我有一个名为data1的数据,名为'hours'和'location'。在输出中,我想按位置查找异常值并以'小时'命名。我尝试使用substitute(y)等等,输出总是使用'​​y'作为列名。任何人都可以帮我吗?谢谢。如何将用户定义函数的参数传递为data.table中的列名称?

mf<-function(data, y){ 
newy<-as.name(deparse(substitute(y))) 
output<-data[,.(y=boxplot.stats(eval(newy))$out),by=.(location)] 
return(output) 
} 
mf(data=data1,y=hours) 
+0

请参阅https://*.com/questions/5963269/how-to-make-a-great-r-reproducible-example/28481250#28481250关于如何成为一个好例子。 – Frank

最好编写带字符值的函数来选择列。在这种情况下,你的函数可以改写为:

mf <- function(data, y){ 
    output <- data[, boxplot.stats(get(y))['out'], by = .(location)] 
    setnames(output, 'out', y) 
    return(output) 
} 

通过使用[到子集boxplot.stats输出,命名列表包含一个元素('out')返回。所以output将有两列:locationout。那么你只需要将out更改为y

例子:

set.seed(100) 
data1 <- data.table(
    location = state.name, 
    hours = rpois(1000, 12) 
) 
mf(data = data1, y = 'hours') 
#   location hours 
# 1:  Delaware 25 
# 2:  Georgia 21 
# 3:   Idaho  4 
# 4: Massachusetts  5 
# 5:  Missouri  7 
# 6: South Carolina  5 
# 7: South Carolina  6 
# 8: South Dakota 20 
# 9:   Texas  5 
# 10:   Utah 22 

非标评价是棘手的,只值,如果你能得到的东西它的努力。 data.table将其用于幕后优化。 tidyverse包使用它来允许数据库内处理。如果没有任何好处(除了不必输入几个引号),只需要一笔费用。

+0

谢谢Nathan Werth,你的代码有效。感谢您指出eval()的麻烦。这里的例子很简单,只有位置和时间。在我的真实代码中,还有一列 - 晶须的端点(boxplot(hours)$ stats [5])。因此,我无法使用['out']。但我设法做boxplot(小时)$ out并使用setnames(输出,'V1',y)重命名V1列。谢谢。 – DrX

+0

顺便说一句,谢谢你提供这个问题的解决方案。我只是觉得引用引号来引用R函数参数中的列是不常见的。 – DrX