This seems a rudimental question but I can't find an explanation on SO.
I can name a vector like so:
values = c("lab1" = "my_lab1",
"lab2" = "my_lab2")
values
# lab1 lab2
# "my_lab1" "my_lab2"
I can create the same vector by using paste0
to create an element like so:
values = c("lab1" = "my_lab1",
"lab2" = paste0("my_lab", "2"))
values
# lab1 lab2
# "my_lab1" "my_lab2"
But when you try to create the name with paste0
, it causes an error:
values = c("lab1" = "my_lab1",
paste0("lab", "2") = "my_lab2")
# Error: unexpected '=' in:
# "values = c("lab1" = "my_lab1",
# paste0("lab", "2") ="
Why is this? Considering that the following is true:
identical("lab2", paste0("lab", "2"))
[1] TRUE
A solution is to use setNames
but I am interested in why the above is an issue:
setNames(c("my_lab1", "my_lab2"), c("lab1", paste0("lab", "2")))
# lab1 lab2
# "my_lab1" "my_lab2"
I can't see any mention to this in the vector
section of Advanced R.
Thanks
The problem is that named parameters are simply never evaluated. They are assumed to be literal values. Consider the case of
foo <- function(a=5, x=10) {a+x}
And then you did
x <- "a"
foo(x = 2)
foo(paste(x) = 2) # error
If you expect the "x" to be evaluated, it can get very confusing what actually is supposed to run. The R parser does not expect to see expressions as parameter names. The grammar is defined in the R source code There is also a reference to this fact in the R Language Definition where it states
Each argument can be tagged (tag=expr), or just be a simple expression. It can also be empty or it can be one of the special tokens ..., ..2, etc. [...] A tag can be an identifier or a text string.
which does imply the tag cannot be an expression itself.
In the example I used foo
as a function, but c
is also just a function. And while it doesn't' have explicit named parameters, it does follow all the same rules for other functions about parameter names.
In the tidyverse/rlang world, they defined a new function :=
which allows you to use names for parameters
rlang::list2("lab1" = "my_lab1",
!!paste0("lab", "2") := "my_lab2")
# $lab1
# [1] "my_lab1"
# $lab2
# [1] "my_lab2"
but in order to do this, it's just not possible to use =
, they had to use :=
which is a function in R, not a special character, and they manually re-write the call when executing it.