使用点点点(...)表示从data.table对象的自定义函数返回的列

Mia*_*Cai 4 r function ellipsis data.table

我想用来...指示要从对象的自定义函数返回的变量data.table。这是一个最小的可复制示例:

library(data.table)
d = data.table(mtcars)

getvar = function(...){
  return(d[,.(xyz = mean(hp), ...), cyl])
}

getvar(mpg, cyl, disp)
Run Code Online (Sandbox Code Playgroud)

在错误[.data.table(d,(N = .N,...),CYL):对象'CYL'未找到

我希望得到的是:

d[,.(xyz = mean(hp), mpg, cyl, disp), cyl]

 #    cyl       xyz  mpg cyl  disp
 # 1:   6 122.28571 21.0   6 160.0
 # 2:   6 122.28571 21.0   6 160.0
 # 3:   6 122.28571 21.4   6 258.0
 # 4:   6 122.28571 18.1   6 225.0
 # 5:   6 122.28571 19.2   6 167.6
Run Code Online (Sandbox Code Playgroud)

任何人都可以分享他们的解决方案吗?

Jaa*_*aap 5

一个可能的解决方案是mget在函数中使用,它返回一个列表,然后xyz与结合使用c。要进行此工作,需要将要添加的列指定为字符向量:

getvar = function(...){
  return(d[, c(xyz = mean(hp), mget(...)), cyl])
}

getvar(c("mpg", "cyl", "disp"))
Run Code Online (Sandbox Code Playgroud)

这使:

> getvar(c("mpg", "cyl", "disp"))
    cyl       xyz  mpg cyl  disp
 1:   6 122.28571 21.0   6 160.0
 2:   6 122.28571 21.0   6 160.0
 3:   6 122.28571 21.4   6 258.0
 4:   6 122.28571 18.1   6 225.0
 5:   6 122.28571 19.2   6 167.6
 6:   6 122.28571 17.8   6 167.6
 7:   6 122.28571 19.7   6 145.0
 8:   4  82.63636 22.8   4 108.0
 9:   4  82.63636 24.4   4 146.7
10:   4  82.63636 22.8   4 140.8
....
Run Code Online (Sandbox Code Playgroud)

或者,也可以选择@Rhonak答案的细微变化(对@ zx8754表示感谢):

getvar = function(...){
  mc <- match.call(expand.dots = FALSE)
  x <- as.character(mc$...)
  d[, c(xyz = mean(hp), mget(x)), cyl]
}

getvar(mpg, cyl, disp)
Run Code Online (Sandbox Code Playgroud)