我想将列表的某些属性作为函数的参数传递。
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)
模式。
这样做的简单方法是什么?感谢。
答案 0 :(得分:1)
在您的代码中,data
和attr
两个不同的变量被传递到函数中 - 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?的答案。