我正在尝试使用lazyeval::interp
按照Non-standard evaluation vignette中的建议混合常量和引用的变量名称。
这是一个做我想要的例子:
# create sample dataset
df_foo = data_frame(
`(Weird) Variable name` = 100,
group_var = sample(c("Yes", "No"), size = 100, replace = TRUE)
)
# function to update the value of weirdly named variable
update_var_1 = function(var_name) {
df_foo %>%
mutate_(
"(Weird) Variable name" =
interp(quote(ifelse(group_var_val == "Yes", var_name_val/10, var_name_val/20)),
group_var_val = as.name("group_var"),
var_name_val = as.name(var_name))
)
}
# test the function
update_var_1("(Weird) Variable name") %>%
head(n = 20)
请注意,我已将延迟评估的结果分配给字符向量("(Weird) Variable name"
)。但是,当我将延迟评估的结果分配给var_name
并将其分配给名为"var_name"
的文字时。有人可以帮助理解这种行为吗?
# function to update the value of weirdly named variable
update_var_2 = function(var_name) {
df_foo %>%
mutate_(
var_name =
interp(quote(ifelse(group_var_val == "Yes", var_name_val/10, var_name_val/20)),
group_var_val = as.name("group_var"),
var_name_val = as.name(var_name))
)
}
# test the function
update_var_2("(Weird) Variable name") %>%
head(n = 20)
两个功能是否应该没有相同的结果?
答案 0 :(得分:20)
直接调用任何R函数时,不能将变量用于参数名称(并且参数名称是指函数调用中=
符号左侧的那些内容)。参数名称始终作为文字值。这两个是相同的
f(a=3)
f("a"=3)
或者看看
deparse(quote(f(a=3)))
# [1] "f(a = 3)"
deparse(quote(f("a"=3)))
# [1] "f(a = 3)"
a <- "b"
deparse(quote(f(a=3)))
# [1] "f(a = 3)"
a
不必是第一个工作的变量,即使存在这样的变量,它也会被忽略。解析时基本上抛出了引号 - 它实际上不是字符值,而是符号。
如果需要动态设置变量名,则需要将参数构建为列表并设置该列表的名称。
如果要将参数名称作为字符值传递,可以使用setNames
设置参数名称,然后将其传递给.dots=
的{{1}}参数功能。例如
mutate_
这是因为这些都是等价的
update_var_3 <- function(var_name) {
df_foo %>%
mutate_(.dots=
setNames(list(
interp(quote(ifelse(group_var_val == "Yes", var_name_val/10, var_name_val/20)),
group_var_val = as.name("group_var"),
var_name_val = as.name(var_name)
)), var_name))
}
update_var_3("(Weird) Variable name") %>%
head(n = 20)