尝试在R中应用非功能错误

时间:2015-08-05 07:23:23

标签: r

我想将列表的某些属性作为函数的参数传递。

foo <- function(lst, attr) {
   # lst is a list
   # I want to transform attr into 'factor' mode.
    data$substitute(attr) <- as.factor(lst$substitute(attr))
}

此代码段失败,错误信息“尝试应用非功能”。 实际上,data$substitute(attr)未能获得attr的{​​{1}}属性。

具体示例如下: 让我们创建一个名为lst的列表。

lst

然后lst <- list() lst$CLICK_DT <- c(as.Date("2015-07-01"), as.Date("2015-07-02")) lst$CLICK <- c(111,123) 未能获得lst$substitute(CLICK_DT)的{​​{1}}属性。

CLICK_DT应将lst转换为foo(lst, CLICK)模式,lst$CLICK应将factor转换为foo(lst,CLICK_DT)模式。

这样做的简单方法是什么?感谢。

2 个答案:

答案 0 :(得分:1)

在您的代码中,dataattr 两个不同的变量被传递到函数中 - attr 不是 data中的属性(即列)。所以,只需这样做:

foo <- function(data, attr) {
  # Transform attr into 'factor' mode thus:
  attr <- factor(attr)
}

...而且你已经完成了(事实上,如果这是你的所有功能,你甚至不需要传递data变量,只使用function(attr)会工作得很好。

然后,如果attr应该是数据框中的列,那么在将变量传递给函数时使用$符号:

# declare the function
foo <- function(attr) {
      # Transform attr into 'factor' mode thus:
      attr <- factor(attr)
    }

# use it thus
foo(data$attr) #notice the dollar sign - you're passing one of the variables

希望这有帮助!

答案 1 :(得分:0)

我看到您尝试使用substitute()应用非标准参数评估,以允许使用未加引号的符号作为foo()的第二个参数来指定目标列表组件。以下是如何做到这一点:

foo <- function(lst,name.arg) {
    name.sym <- substitute(name.arg);
    if (typeof(name.sym) != 'symbol') stop('name must be a symbol.');
    name.str <- as.character(name.sym);
    lst[[name.str]] <- as.factor(lst[[name.str]]);
    lst;
};
lst <- list(CLICK_DT=c(as.Date('2015-07-01'),as.Date('2015-07-02')),CLICK=c(111,123));
lst;
## $CLICK_DT
## [1] "2015-07-01" "2015-07-02"
##
## $CLICK
## [1] 111 123
##
sapply(lst,class);
##  CLICK_DT     CLICK
##    "Date" "numeric"
lst <- foo(foo(lst,CLICK_DT),CLICK);
lst;
## $CLICK_DT
## [1] 2015-07-01 2015-07-02
## Levels: 2015-07-01 2015-07-02
##
## $CLICK
## [1] 111 123
## Levels: 111 123
##
sapply(lst,class);
## CLICK_DT    CLICK
## "factor" "factor"

其他几点:你误用了“属性”这个词。在R中,“属性”是一个明确定义的术语,指的是附加到另一个(主)数据对象的辅助数据对象。您可以使用attr()attributes()读取/写入对象的属性。你应该在这里使用的词是“组件”,因为我们讨论的是列表组件。您也可以使用单词“element”,因为列表被视为一种向量,甚至在R源中被称为“泛型向量”。

其次,美元操作符实际上是一个函数。当您使用substitute()访问表达式的解析树时,如果表达式涉及美元运算符,则返回值的类型将为'language'(包含类'call'或{{ 1}}如果被支撑块包围),而不是'{'(类'symbol')。普通函数调用也是如此,例如'name'也返回类型typeof(substitute(sum(1,2)))(并且还有类'language')。

您的要求可以通过不同的方式实施。您可以支持文字字符串或符号(如我所示),甚至可以对参数的解析树应用某种复杂的分析,例如接受美元调用并从生成的解析树中提取RHS,并使用该符号作为组件名称。您甚至可以通过类型检测参数的解析树,使用单个函数定义来支持部分或全部这些接口,尽管这会增加复杂性。我认为这不值得;我在上面写'call'的方式我认为是最好的设计,因为实现很简单,但它也为调用者提供了最大的便利,因为他们可以使用不带引号的符号指定目标列表组件。

有关R解析树的更多信息,请参阅What is "{" class in R?的答案。