477

I have a data frame called "newprice" (see below) and I want to change the column names in my program in R.

> newprice
   Chang.  Chang.   Chang.
1     100       36      136
2     120      -33       87
3     150       14      164

In fact this is what am doing:

names(newprice)[1]<-paste("premium")
names(newprice)[2]<-paste("change")
names(newprice)[3]<-paste("newprice") 

I have not put this in a loop because I want each column name to be different as you see.

When I paste my program into R console this is the output it gives me:

> names(newprice)[1]<-paste(“premium”)
Error: unexpected input in "names(newprice)[1]<-paste(“"
> names(newprice)[2]<-paste(“change”)
Error: unexpected input in "names(newprice)[2]<-paste(“"
> names(newprice)[3]<-paste(“newpremium”)
Error: unexpected input in "names(newprice)[3]<-paste(“"

I have equally tried using the c() function-for example c("premium"), instead of the paste() function, but to no avail.

Could someone help me to figure this out?

ZygD
  • 22,092
  • 39
  • 79
  • 102
Son
  • 5,295
  • 5
  • 19
  • 10
  • 1
    If Dirk's answer works then the problem was that you were working with a matrix rather than with a dataframe. You can check this with either `is.matrix` or `str`. – IRTFM May 21 '11 at 12:17
  • 5
    See this answer on dplyr::rename http://stackoverflow.com/a/26146202/1831980 – Rasmus Larsen Feb 08 '16 at 11:53
  • 17
    `colnames(newprice)<- c("premium","change","newprice")` – Tung Nguyen Jul 20 '16 at 07:00
  • 4
    Your error has nothing to do with the quality of your code. You're just using the wrong symbol. This “ is not recognized by R, use " instead. I know they may look the same. Look close: “ ". That's it. – Edo Nov 30 '19 at 01:44
  • Several answers below using a hard-coded position, for instance, `2` in `colnames(X)[2]`. This is usually a not good practice because it is sensitive to data change. What if you add another column before this specific column to your data? Instead, try something like the answer provided by **Hagos**. – Jia Gao May 25 '22 at 00:04

19 Answers19

685

Use the colnames() function:

R> X <- data.frame(bad=1:3, worse=rnorm(3))
R> X
  bad     worse
1   1 -2.440467
2   2  1.320113
3   3 -0.306639
R> colnames(X) <- c("good", "better")
R> X
  good    better
1    1 -2.440467
2    2  1.320113
3    3 -0.306639

You can also subset:

R> colnames(X)[2] <- "superduper"
Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725
  • 16
    @Dirk Why not using names() instead of colnames()? – Antoine Lizée Oct 10 '13 at 06:40
  • 9
    Great! You can also subset multiple columns at once (useful on big data frames). `colnames(X)[c(1,2)] <- c("good", "better")` – metakermit Nov 13 '13 at 12:07
  • 8
    Try `setnames()` in the `data.table` package. Use something like `setnames(DT,"b","B")` or `setnames(DT,c("a","E"),c("A","F"))` – dwstu Aug 11 '14 at 17:23
  • Weirdly, after setting the column names of the data frame `q1`, trying to mutate the data frame using `dplyr` as in `q1 <- q1 %>% mutate(rel_count = count / 482462)` results in the error `Error in mutate_impl(.data, dots) : unknown column 'days'` (where `days` is a new name given to the column). This is really frustrating. – David Tonhofer Feb 07 '17 at 21:19
232

I use this:

colnames(dataframe)[which(names(dataframe) == "columnName")] <- "newColumnName"
Rorschach
  • 31,301
  • 5
  • 78
  • 129
Matheus Abreu
  • 3,357
  • 1
  • 18
  • 21
  • 11
    Thank you. I think this is somehow annoying with R: Why is it so difficult to change the column name if you do not want to use the index number but the old name :( – Arne Mar 18 '14 at 14:41
  • 12
    This method has the advantage that you do not have to worry about the position of the column, as long as you know its original name. I think this is the preferred method as you may - later - make changes to the code that change the position of the column you want to rename. – Paulo S. Abreu Dec 21 '15 at 19:00
  • 1
    Can also use `data.table::setnames(dataframe,'Old','New')` – kakarot Jan 03 '22 at 19:23
90

The error is caused by the "smart-quotes" (or whatever they're called). The lesson here is, "don't write your code in an 'editor' that converts quotes to smart-quotes".

names(newprice)[1]<-paste(“premium”)  # error
names(newprice)[1]<-paste("premium")  # works

Also, you don't need paste("premium") (the call to paste is redundant) and it's a good idea to put spaces around <- to avoid confusion (e.g. x <- -10; if(x<-3) "hi" else "bye"; x).

Joshua Ulrich
  • 173,410
  • 32
  • 338
  • 418
75

Try:

names(newprice)[1] <- "premium"
zx8754
  • 52,746
  • 12
  • 114
  • 209
Jamie
  • 5,994
  • 1
  • 18
  • 15
55

The new recommended way to do this is to use the setNames function. See ?setNames. Since this creates a new copy of the data.frame, be sure to assign the result to the original data.frame, if that is your intention.

data_frame <- setNames(data_frame, c("premium","change","newprice"))

Newer versions of R will give you warning if you use colnames in some of the ways suggested by earlier answers.

If this were a data.table instead, you could use the data.table function setnames, which can modify specific column names or a single column name by reference:

setnames(data_table, "old-name", "new-name")
MichaelChirico
  • 33,841
  • 14
  • 113
  • 198
Scott C Wilson
  • 19,102
  • 10
  • 61
  • 83
52

I had the same issue and this piece of code worked out for me.

names(data)[names(data) == "oldVariableName"] <- "newVariableName"

In short, this code does the following:

names(data) looks into all the names in the dataframe (data)

[names(data) == oldVariableName] extracts the variable name (oldVariableName) you want to get renamed and <- "newVariableName" assigns the new variable name.

Desta Haileselassie Hagos
  • 23,140
  • 7
  • 48
  • 53
28

Similar to the others:

cols <- c("premium","change","newprice")
colnames(dataframe) <- cols

Quite simple and easy to modify.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Adam Erickson
  • 6,027
  • 2
  • 46
  • 33
23

Use this to change column name by colname function.

colnames(newprice)[1] = "premium"
colnames(newprice)[2] = "change"
colnames(newprice)[3] = "newprice"
Sophanna
  • 347
  • 2
  • 7
13

If you need to rename not all but multiple column at once when you only know the old column names you can use colnames function and %in% operator. Example:

df = data.frame(bad=1:3, worse=rnorm(3), worst=LETTERS[1:3])

   bad      worse    worst
1   1 -0.77915455       A
2   2  0.06717385       B
3   3 -0.02827242       C

Now you want to change "bad" and "worst" to "good" and "best". You can use

colnames(df)[which(colnames(df) %in% c("bad","worst") )] <- c("good","best")

This results in

  good      worse  best
1    1 -0.6010363    A
2    2  0.7336155    B
3    3  0.9435469    C
discipulus
  • 2,665
  • 3
  • 34
  • 51
13

My column names is as below

colnames(t)
[1] "Class"    "Sex"      "Age"      "Survived" "Freq" 

I want to change column name of Class and Sex

colnames(t)=c("STD","Gender","AGE","SURVIVED","FREQ")
Mehul Katara
  • 907
  • 11
  • 32
13

There are a couple options with dplyr::rename() and dplyr::select():

library(dplyr)

mtcars %>% 
  tibble::rownames_to_column('car_model') %>%                            # convert rowname to a column. tibble must be installed.
  select(car_model, est_mpg = mpg, horse_power = hp, everything()) %>%   # rename specific columns and reorder
  rename(weight = wt, cylinders = cyl) %>%                               # another option for renaming specific columns that keeps everything by default
  head(2)
      car_model est_mpg horse_power cylinders disp drat weight  qsec vs am gear carb
1     Mazda RX4      21         110         6  160  3.9  2.620 16.46  0  1    4    4
2 Mazda RX4 Wag      21         110         6  160  3.9  2.875 17.02  0  1    4    4

There are also three scoped variants of dplyr::rename(): dplyr::rename_all() for all column names, dplyr::rename_if() for conditionally targeting column names, and dplyr::rename_at() for select named columns. The following example replaces spaces and periods with an underscore and converts everything to lower case:

iris %>%  
  rename_all(~gsub("\\s+|\\.", "_", .)) %>% 
  rename_all(tolower) %>% 
  head(2)
  sepal_length sepal_width petal_length petal_width species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa

dplyr::select_all() can also be used in a similar way:

iris %>%  
  select_all(~gsub("\\s+|\\.", "_", .)) %>% 
  select_all(tolower) %>% 
  head(2)
  sepal_length sepal_width petal_length petal_width species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
sbha
  • 9,802
  • 2
  • 74
  • 62
10

try:

names(newprice) <- c("premium", "change", "newprice")
Smern
  • 18,746
  • 21
  • 72
  • 90
ngamita
  • 329
  • 2
  • 12
10

Just to correct and slightly extend Scott Wilson answer.
You can use data.table's setnames function on data.frames too.

Do not expect speed up of the operation but you can expect the setnames to be more efficient for memory consumption as it updates column names by reference. This can be tracked with address function, see below.

library(data.table)
set.seed(123)
n = 1e8

df = data.frame(bad=sample(1:3, n, TRUE), worse=rnorm(n))
address(df)
#[1] "0x208f9f00"
colnames(df) <- c("good", "better")
address(df)
#[1] "0x208fa1d8"
rm(df)

dt = data.table(bad=sample(1:3, n, TRUE), worse=rnorm(n))
address(dt)
#[1] "0x535c830"
setnames(dt, c("good", "better"))
address(dt)
#[1] "0x535c830"
rm(dt)

So if you are hitting your memory limits you may consider to use this one instead.

jangorecki
  • 16,384
  • 4
  • 79
  • 160
8

You can just do the editing by:

newprice <- edit(newprice)

and change the column name manually.

Baykal
  • 569
  • 2
  • 10
  • 15
  • Doesn't this work only for vector and factor elements? `> locanatmodelset<-edit(locanatmodelset) Error in edit.data.frame(locanatmodelset) : can only handle vector and factor elements` – vagabond Jul 27 '14 at 17:04
  • It works for data frames at least. That's what I know. – Baykal Jul 30 '14 at 01:25
3

This may be helpful:

rename.columns=function(df,changelist){
  #renames columns of a dataframe
  for(i in 1:length(names(df))){
    if(length(changelist[[names(df)[i]]])>0){
      names(df)[i]= changelist[[names(df)[i]]]
    }
  }
  df
}

# Specify new dataframe
df=rename.columns(df,list(old.column='new.column.name'))
Dave Gruenewald
  • 5,329
  • 1
  • 23
  • 35
Chris
  • 1,219
  • 2
  • 11
  • 21
2

In case we have 2 dataframes the following works

 DF1<-data.frame('a', 'b')
 DF2<-data.frame('c','d')

We change names of DF1 as follows

 colnames(DF1)<- colnames(DF2)
Raghavan vmvs
  • 1,213
  • 1
  • 10
  • 29
2

Change data frame column name

colnames(dataset)[colnames(dataset) == 'name'] <- 'newcolumnname'
Henry Ecker
  • 34,399
  • 18
  • 41
  • 57
Rupesh Kumar
  • 157
  • 3
1

One option using data.table:

library(data.table)

setDT(dataframe)

setnames(dataframe,'Old1','New1')
setnames(dataframe,'Old2','New2')
kakarot
  • 376
  • 4
  • 13
-1

This works for me:

newprice<- setNames(newprice, c("premium", "change", "newprice"))
Abdelah
  • 9
  • 1