46

Is there any way to use string stored in variable as a column name in a new data frame? The expected result should be:

col.name <- 'col1'
df <- data.frame(col.name=1:4)
print(df)

# Real output
  col.name
1        1
2        2
3        3
4        4

# Expected output
  col1
1    1
2    2
3    3
4    4

I'm aware that I can create data frame and then use names() to rename column or use df[, col.name] for existing object, but I'd like to know if there is any other solution which could be used during creating data frame.

Adam H
  • 731
  • 2
  • 10
  • 16

3 Answers3

41

You cannot pass a variable into the name of an argument like that.

Instead what you can do is:

df <- data.frame(placeholder_name = 1:4)
names(df)[names(df) == "placeholder_name"] <- col.name

or use the default name of "V1":

df <- data.frame(1:4)
names(df)[names(df) == "V1"] <- col.name

or assign by position:

df <- data.frame(1:4)
names(df)[1] <- col.name

or if you only have one column just replace the entire names attribute:

df <- data.frame(1:4)
names(df) <- col.name

There's also the set_names function in the magrittr package that you can use to do this last solution in one step:

library(magrittr)
df <- set_names(data.frame(1:4), col.name)

But set_names is just an alias for:

df <- `names<-`(data.frame(1:4), col.name)

which is part of base R. Figuring out why this expression works and makes sense will be a good exercise.

shadowtalker
  • 12,529
  • 3
  • 53
  • 96
6

In addition to ssdecontrol's answer, there is a second option.

You're looking for mget. First assign the name to a variable, then the value to the variable that you have previously assigned. After that, mget will evaluate the string and pass it to data.frame.

assign("col.name", "col1")
assign(paste(col.name), 1:4)

df <- data.frame(mget(col.name))
print(df)
  col1
1    1
2    2
3    3
4    4
AndOne
  • 171
  • 1
  • 1
  • 9
Chris C
  • 1,625
  • 1
  • 19
  • 22
0

I don't recommend you do this, but:

col.name <- 'col1'
eval(parse(text=paste0('data.frame(', col.name, '=1:4)')))
Zach
  • 29,791
  • 35
  • 142
  • 201
  • 4
    This indeed is a very bad way to do it. Parsing arbitrary text values is dangerous and should be avoided. – MrFlick May 06 '15 at 17:30