0

Why can't I use paste to construct a string in c()?

c("SomeKey" = 123)

is Ok and prints as:

SomeKey 
    123 

but

a1 <- "Some"
a2 <- "Key"
c(paste(a1, a2) = 123)

produces:

Error: unexpected '=' in "    c(paste(a1, a2) ="

Strangely enough, I can do this:

key <- paste(a1, a2)
c(key = 123)
jcoppens
  • 5,306
  • 6
  • 27
  • 47
  • There is no function called `"paste<-"` in R so it won't work in any case. It's strange though how `c` works. It seems like sometimes it produces the actual error, like for example `c("a" = "D"*5)` and sometimes the error you've got. And sometimes it gives an error though the function actually did work like `x <- 1:4 ; c("a" = names(x) = letters[1:4])`. Though the later is probably because it has no where to assign to. Worth checking the source code though – David Arenburg May 31 '15 at 14:40
  • 1
    a nice sunday project for you @DavidArenburg :} – rawr May 31 '15 at 14:44
  • @DavidArenburg: David, I'm just beginning to play with R, so maybe I'm missing something basic here. I don't know what you mean by "There is no function called "paste<-" in R". Shouldn't a call to a function be replaced by its result? – jcoppens May 31 '15 at 14:50
  • See [here](http://stackoverflow.com/questions/10449366/levels-what-sorcery-is-this) – David Arenburg May 31 '15 at 14:53
  • 2
    @DavidArenburg : I think it doesn't have to do with a non-existing `paste<-` or with `c`; rather it seems like a parsing issue. Reading the console, R seems to evaluate the arguments inside the recognized `c` function; `paste(a1, a2)` is evaluated and "=" is left in the middle of nowhere to be parsed (e.g. type ` = 123` in the console). The "no `paste<-` error" you describe is seen in `paste(a1, a2) = 123` where the LHS and RHS are not evaluated immediately (as inside `c`). – alexis_laz May 31 '15 at 16:48
  • @alexis_laz you probably right, though it would be still fail if it would be parsed. – David Arenburg May 31 '15 at 17:15
  • @DavidArenburg Should I submit this as a bug? – jcoppens May 31 '15 at 21:19
  • @jcoppens I don't think it's a bug. – David Arenburg May 31 '15 at 21:20
  • 1
    In your last example, note that you get a vector with name "key" instead of a vector with name "Some Key". – josliber Jun 01 '15 at 00:43

3 Answers3

6

You are looking for setNames, which returns a named vector with the specified names and values:

setNames(123, paste0(a1, a2))
# SomeKey 
#     123 
all.equal(setNames(123, paste0(a1, a2)), c("SomeKey" = 123))
# [1] TRUE
josliber
  • 43,891
  • 12
  • 98
  • 133
  • That *is* a nice solution! And I'll use it for now. I am a little worried - which is why I asked the question in the first place - why I cannot use `paste` in `c()`. – jcoppens May 31 '15 at 14:37
2

Because paste() or paste0() returns a character vector - it can return vectors of greater than length one. You're trying assign a vector as a name to a single object. Why not name the vector after the fact?

a = c(123,456)
names(a)=c(paste0("Some","Key"),paste0("Some","Other","Key"))
a
#> SomeKey SomeOtherKey 
       123          456 
Mark
  • 4,387
  • 2
  • 28
  • 48
  • Character vector is not a problem here. There are no scalars in R (`x <- 1; is.vector(x)`) – zero323 May 31 '15 at 14:27
  • @zero323 but the same error exhibits itself in `c(c("SomeKey")=123)` so there's something in `c()` which accepts a string as a name but not a vector. I understand that in R there are no scalars but within the function call it's handled differently if it's explicitly provided as a vector. – Mark May 31 '15 at 14:30
  • 1
    @zero323 for that matter, `c(12=145)` throws the error, but `a = 145;names(a)=12` works as does `setNames(145,12)`. So maybe it's not the vector issue specifically, but setting a name inside of `c()` is very particular about what it accepts. – Mark May 31 '15 at 14:34
  • `c(12=145)` fails because `12` is treated as numeric constant here so R tries to evaluate it. `names(a) = 12` works because names converts `12` to character vector. It is still not a valid name but it is a different story. – zero323 May 31 '15 at 14:41
0

You are probably looking for assign. You may want to use paste0, as it doesn't put a space between the things it's pasting... or sep="" with paste

> a1 <- "Some"
> a2 <- "Key"
> assign(paste(a1, a2), 123)
> ls()
[1] "a1"       "a2"       "Some Key"
> `Some Key`
[1] 123
cory
  • 6,529
  • 3
  • 21
  • 41
  • Thanks, but no, I really want to construct keys. The keys are very large, and I didn't want to repeat them. They have a long common part, such as 'abcdefghijklmnopqrstuvwxyz01', and only the last digits change. – jcoppens May 31 '15 at 14:26
  • No? This is the single use version of the `setNames` solution you are using. Try `?assign` and `?setNames` and choose which one work best for your use case. – cory May 31 '15 at 14:57