David M. Perlman
David M. Perlman

Reputation: 5070

Rename multiple variables within a pipeline

The pipeline metaphor enabled by packages like dplyr and magrittr is incredibly useful and does great things for making your code readable in R (a daunting task!)

How can one make a pipeline that ended with renaming all the variables in a data frame to a pre-determined list?

Here is what I tried. First, simple sample data to test on:

> library(dplyr)    
> iris %>% head(n=3) %>% select(-Species) %>% t %>% as.data.frame -> test.data
> test.data

               1   2   3
Sepal.Length 5.1 4.9 4.7
Sepal.Width  3.5 3.0 3.2
Petal.Length 1.4 1.4 1.3
Petal.Width  0.2 0.2 0.2

This doesn't work:

> test.data %>% rename(a=1,b=2,c=3)
Error: Arguments to rename must be unquoted variable names. Arguments a, b, c are not.

I wasn't able to figure out the precise meaning of this error from reading the documentation on rename. My other attempt avoids an error by using curly braces to define a code block, but the renaming doesn't actually happen:

> test.data %>% { names(.) <- c('a','b','c')}

Upvotes: 5

Views: 5855

Answers (3)

Keiku
Keiku

Reputation: 8803

We can rename the numerical variable names with dplyr::rename by enclosing in Backquote(`).

library(dplyr)

iris %>% 
  head(n=3) %>% select(-Species) %>% t %>% as.data.frame %>%
  dplyr::rename(a=`1`, b=`2`, c=`3`)
# a   b   c
# Sepal.Length 5.1 4.9 4.7
# Sepal.Width  3.5 3.0 3.2
# Petal.Length 1.4 1.4 1.3
# Petal.Width  0.2 0.2 0.2

As another way, we can set column name by using stats::setNames, magrittr::set_names and purrr::set_names.

library(dplyr)
library(magrittr)
library(purrr)

iris %>% 
  head(n=3) %>% select(-Species) %>% t %>% as.data.frame %>%
  stats::setNames(c("a", "b", "c"))

iris %>% 
  head(n=3) %>% select(-Species) %>% t %>% as.data.frame %>%
  magrittr::set_names(c("a", "b", "c"))

iris %>% 
  head(n=3) %>% select(-Species) %>% t %>% as.data.frame %>%
  purrr::set_names(c("a", "b", "c"))
# The results of above all codes is as follows:
# a   b   c
# Sepal.Length 5.1 4.9 4.7
# Sepal.Width  3.5 3.0 3.2
# Petal.Length 1.4 1.4 1.3
# Petal.Width  0.2 0.2 0.2

Upvotes: 2

David M. Perlman
David M. Perlman

Reputation: 5070

The way I got this to work, I needed the tee operator from the magrittr package:

> library(magrittr)
> test.data %T>% { names(.) <- c('a','b','c')} -> renamed.test.data
> renamed.test.data
               a   b   c
Sepal.Length 5.1 4.9 4.7
Sepal.Width  3.5 3.0 3.2
Petal.Length 1.4 1.4 1.3
Petal.Width  0.2 0.2 0.2

Note that for a data frame with normal (i.e. not numbers) variable names, you can do this:

> # Rename it with rename in a normal pipe
> renamed.test.data %>% rename(x=a,y=b,z=c) -> renamed.again.test.data
> renamed.again.test.data
               x   y   z
Sepal.Length 5.1 4.9 4.7
Sepal.Width  3.5 3.0 3.2
Petal.Length 1.4 1.4 1.3
Petal.Width  0.2 0.2 0.2

The above trick (edit: or, even better, using setNames) is still useful, though, because sometimes you already have the list of names in a character vector and you just want to set them all at once without worrying about writing out each replacement pair.

Upvotes: 2

mtelesha
mtelesha

Reputation: 2179

'1','2','3'You were correct except use setNames {stats} instead of rename (zx8754 answered in your comment before me)

setNames: This is a convenience function that sets the names on an object and returns the object. It is most useful at the end of a function definition where one is creating the object to be returned and would prefer not to store it under a name just so the names can be assigned.

Your example (Close just change rename with setNames)

iris %>% 
   head(n=3) %>% 
   select(-Species) %>% 
   t %>% 
   as.data.frame %>% 
   rename(a=1,b=2,c=3)

Answer

iris %>% 
   head(n=3) %>% 
   select(-Species) %>%
   t %>%
   as.data.frame %>%
   setNames(c('1','2','3'))

Another Example

name_list <- c('1','2','3')

iris %>% 
   head(n=3) %>% 
   select(-Species) %>%
   t %>%
   as.data.frame %>%
   setNames(name_list)

Upvotes: 5

Related Questions