首页 > 解决方案 > 将名称传递给函数是否有一致的指导?以 data.table 为例

问题描述

data(survey)
df <- survey
df$Sex <- as.character(df$Sex)

test <- function(x, y, z){
  a <- setDT(x)[, z := .N - 1L, by=y]
  setDF(a)
}

test2 <- function(x, y, z){
  a <- setDT(x)[, z := .N - 1L, by=substitute(y)]
  setDF(a)
}

test3 <- function(x, y, z){
  a <- setDT(x)[, z := .N - 1L, by=c(deparse(substitute(y))]
  setDF(a)
}

test(df, Sex, dup)
test2(df, Sex, dup)
test3(df, Sex, dup)

好的,所以 test 和 test2 返回一个“no object”错误,但 test3 没有。我不知道为什么。我不明白为什么我不能像在函数外键入它那样在函数中传递东西,而且我总是最终只是尝试所有变体,直到其中一个起作用。有没有办法真正了解这些东西?就像在这个例子中一样,为什么 test 和 test2 不起作用?

标签: r

解决方案


  • test不起作用,因为 data.table正在父框架by中寻找对象Sex。by 参数接受列表或向量。这是由参数的惰性评估引起的。y 被评估为 Sex 然后 Sex 未找到导致错误被抛出。
  • 至于test2它基本上是同一个问题,如果你输入typeof(substitute(y))它会返回“符号”,它不是一个列表,而是一个承诺对象R。一种解决方法是将替代调用包含在as.character().
  • 最后一个有效,因为您正在将替代创建的符号转换为字符。

笔记

创建的列将被命名z?data.table::`:=` 帮助表明它的默认行为是采用符号。因此,您需要像对 y 所做的那样替换它并对其进行解析。


推荐阅读