Search code examples
rdplyrrenamenames

renaming a subset of contiguous columns in a data.frame/tible based on name-indexing in R


I want so select a subset of consecutive columns by column name, and rename with a character vector.

example data:

data<-data.frame(foo=1:4, bar=10:13, zoo_1=letters[1:4], zoo_2=letters[5:8])

  foo bar zoo_1 zoo_2
1   1  10     a     e
2   2  11     b     f
3   3  12     c     g
4   4  13     d     h

colnames to be replaced: 'bar', 'zoo_1', 'zoo_2'

new names:

new_names<-c('a', 'b', 'c')

I wanted to use some sort of : operator to select, for instance, the columns with the names bar to zoo_2

I found some weird solutions:

#1
names(data)[which(names(df)=='bar'):which(names(df)=='zoo_2')]<-new_names

and

#2
my_rename<-function(x,y,z){
        names(x)[match(y, names(df))]<-z
        names(x)
}
names(data)<-my_rename(data, c('bar', 'zoo_1', 'zoo_2'), c(new_names)

Solution #2 is bad because it requires spelling out all names to be replaced.

Solution #1 allows me to select the names in a 'bar':'zoo_2' style, but is quite verbose and may be confusing to others. I am most interested In a substitute for this (which:which) hack.

Any ideas?


Solution

  • We can use rename_at

    library(dplyr)
    data <- data %>%
               rename_at(vars(bar:zoo_2), ~ new_names)
    names(data)
    #[1] "foo" "a"   "b"   "c"
    

    However, in dplyr 1.05, rename_at has been superseded by rename_with:

    data2<-data %>%
            rename_with(.cols=bar:zoo_2, ~ new_names)
    
    > identical(data, data2)
    [1] TRUE