这似乎是一个基本问题,但我找不到对此的解释。
我可以这样命名一个向量:
values = c("lab1" = "my_lab1",
"lab2" = "my_lab2")
values
# lab1 lab2
# "my_lab1" "my_lab2"
Run Code Online (Sandbox Code Playgroud)
我可以通过使用paste0创建元素来创建相同的向量,如下所示:
values = c("lab1" = "my_lab1",
"lab2" = paste0("my_lab", "2"))
values
# lab1 lab2
# "my_lab1" "my_lab2"
Run Code Online (Sandbox Code Playgroud)
但是当您尝试使用 创建名称时paste0,会导致错误:
values = c("lab1" = "my_lab1",
paste0("lab", "2") = "my_lab2")
# Error: unexpected '=' in:
# "values = c("lab1" = "my_lab1",
# paste0("lab", "2") ="
Run Code Online (Sandbox Code Playgroud)
为什么是这样?考虑到以下情况属实:
identical("lab2", paste0("lab", "2"))
[1] TRUE
Run Code Online (Sandbox Code Playgroud)
解决方案是使用setNames,但我对为什么上述问题很感兴趣:
setNames(c("my_lab1", "my_lab2"), c("lab1", paste0("lab", "2")))
# lab1 lab2
# "my_lab1" "my_lab2"
Run Code Online (Sandbox Code Playgroud)
我在Advanced Rvector部分看不到任何提及这一点。
谢谢
问题在于命名参数根本不会被评估。它们被假定为文字值。考虑以下情况
foo <- function(a=5, x=10) {a+x}
Run Code Online (Sandbox Code Playgroud)
然后你做到了
x <- "a"
foo(x = 2)
foo(paste(x) = 2) # error
Run Code Online (Sandbox Code Playgroud)
如果您期望对“x”进行求值,则实际应该运行的内容可能会变得非常混乱。R 解析器不希望将表达式视为参数名称。语法在 R 源代码中定义。R 语言定义中也引用了这一事实,其中指出
每个参数都可以被标记(tag=expr),或者只是一个简单的表达式。它也可以为空,也可以是特殊标记之一...、..2 等。 [...] 标记可以是标识符或文本字符串。
这确实意味着标签本身不能是表达式。
在示例中我用作foo函数,但c也只是一个函数。虽然它没有显式命名参数,但它确实遵循其他函数有关参数名称的所有相同规则。
在 tidyverse/rlang 世界中,他们定义了一个新函数:=,允许您使用参数名称
rlang::list2("lab1" = "my_lab1",
!!paste0("lab", "2") := "my_lab2")
# $lab1
# [1] "my_lab1"
# $lab2
# [1] "my_lab2"
Run Code Online (Sandbox Code Playgroud)
但为了做到这一点,不可能使用=,他们必须使用:=R 中的函数,而不是特殊字符,并且他们在执行时手动重写调用。