【发布时间】:2016-12-30 20:35:02
【问题描述】:
在标记为 dup 之前,我知道 Use character string as function argument,但我的用例略有不同。我不需要在函数内部传递参数,我想在+ 之后传递动态数量的参数(想想ggplot2)。
(注意:请不要格式化并删除多余的####,我已将它们保留在其中,以便人们可以将代码复制粘贴到 R 中为简单起见)。
这是我的过程:
#### 所以让我们重现这个例子:
library(condformat)
condformat(iris[c(1:5,70:75, 120:125),]) +
rule_fill_discrete(Species) +
rule_fill_discrete(Petal.Width)
#### 我希望能够动态传递两个rule_fill_discrete() 函数(在我的实际用例中,我有可变数量的可能输入,并且不可能将它们硬编码)。
#### 首先,创建一个泛化函数:
PlotSeries <- function(x){
b=NULL
for (i in 1:length(x)){
a <- paste('rule_fill_discrete(',x[i],')',sep="")
b <- paste(paste(b,a,sep="+"))
}
b <- gsub("^\\+","",b)
eval(parse(text = b))
}
#### 与一个参数一起工作
condformat(iris[c(1:5,70:75, 120:125),]) +
PlotSeries("Species")
#### 但如果我们传递两个参数则不会:
condformat(iris[c(1:5,70:75, 120:125),]) +
PlotSeries(c("Species","Petal.Width"))
rule_fill_discrete(Species) + rule_fill_discrete(Petal.Width) 中的错误: 二元运算符的非数字参数
#### 如果我们单独调用每个,它将起作用
condformat(iris[c(1:5,70:75, 120:125),]) +
PlotSeries("Species") +
PlotSeries("Petal.Width")
#### 这给了我们一个关于问题所在的指示......事实上它不喜欢 rule_fill_discrete 语句作为 one 语句传入。让我们测试一下:
condformat(iris[c(1:5,70:75, 120:125),]) +
eval(rule_fill_discrete(Species) +
rule_fill_discrete(Petal.Width) )
rule_fill_discrete(Species) + rule_fill_discrete(Petal.Width) 中的错误: 二元运算符的非数字参数
#### 失败。但是:
condformat(iris[c(1:5,70:75, 120:125),]) +
eval(rule_fill_discrete(Species)) +
eval(rule_fill_discrete(Petal.Width) )
#### 这行得通。但是我们需要能够传入一组语句(这就是重点)。因此,让我们尝试获取 eval 语句:
Nasty <- "eval(rule_fill_discrete(Species)) eval(rule_fill_discrete(Petal.Width))"
condformat(iris[c(1:5,70:75, 120:125),]) + Nasty #### FAIL
+.default(condformat(iris[c(1:5, 70:75, 120:125), ]) 中的错误,讨厌): 二元运算符的非数字参数
condformat(iris[c(1:5,70:75, 120:125),]) + eval(Nasty) #### FAIL
+.default(condformat(iris[c(1:5, 70:75, 120:125), ]), eval(Nasty)) 中的错误: 二元运算符的非数字参数
condformat(iris[c(1:5,70:75, 120:125),]) + parse(text=Nasty) #### FAIL
+.default(condformat(iris[c(1:5, 70:75, 120:125), ]), parse(text = Nasty)) 中的错误: 二元运算符的非数字参数
condformat(iris[c(1:5,70:75, 120:125),]) + eval(parse(text=Nasty)) #### FAIL
eval(rule_fill_discrete(Species)) + eval(rule_fill_discrete(Petal.Width)) 中的错误: 二元运算符的非数字参数
那么我们该怎么做呢?
【问题讨论】:
-
我发现使用“动态”一词的问题通常非常不清楚。这个词有很多不同的可能含义。最好是做一个简单的例子,并说出输入和输出应该是什么。此时我们有了输入,但是所需的输出要么不存在,要么与各种错误消息混在一起,以至于我至少找不到所需输出的正确描述。尝试将宏样式处理与引用的
"eval"混合起来似乎太复杂了。 -
对不起 42,让我试着澄清一下。我从所需的输出开始...我只想创建一个函数,允许我将任意数量的条件格式语句传递给 condformat
-
我想我知道你想要做什么,但是在查看了
condformat包使用的约定之后,我认为标准和非标准评估的混乱混合对我来说太过分了。我不相信标记为 ggplot2 真的是“诚实的”。我不认为+运算符具有相同的评估机制。 -
不确定,但
purrr包的地图功能可能会有所帮助。 -
是的,bungo,谢谢。请参阅我对 Gregor 出色答案的详细阐述......它使用 purrr 函数来应用稍微复杂的用例
标签: r lazy-evaluation