5

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')}
David M. Perlman
  • 4,851
  • 2
  • 16
  • 12
  • I like when people answer their own questions like this. Thanks! (Not a relevant question to me, but I still like it) – Daniel Feb 26 '16 at 16:14
  • 4
    please provide a reproducible example _in your question_. If you didnt answer this yourself, this could be closed for several reasons – rawr Feb 26 '16 at 16:26
  • 1
    I suggest following rawr's advice: put an example into your question. Also, take out the meta-commentary. If you want to chat about self-answering, you can add a comment below your own post. The post should be about the question not about the fact that you answered or that the answer is not as easy as I might think. – Frank Feb 26 '16 at 17:11
  • 2
    The original attempt works with backticks around the numbers `rename(a='1', b='2', c='3')` – Pierre L Feb 26 '16 at 17:57
  • @rawr, I'm not sure what your complaint is. The question contains a reproducible example using data that is in the base installation. What is missing? What "chat" are you talking about? – David M. Perlman Feb 27 '16 at 18:00
  • @DavidM.Perlman it does after the edit, no complaints now – rawr Feb 27 '16 at 19:13
  • I don't understand why this was closed for not being clear? How do you rename columns in pipes from a list should be enough. – mtelesha Mar 15 '16 at 14:30
  • @PierreLafortune Thanks for telling me about the back ticks. That is a painfully google-proof feature of R; I spent hours researching this question online before posting here and never saw any hint of that come up in any searches I tried. – David M. Perlman Mar 16 '16 at 17:42

3 Answers3

5

'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)
mtelesha
  • 2,079
  • 18
  • 16
2

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.

David M. Perlman
  • 4,851
  • 2
  • 16
  • 12
  • 3
    why not `iris %>% head(n=3) %>% select(-Species) %>% t %>% as.data.frame %>% setNames(c('a','b','c'))` – rawr Feb 26 '16 at 16:24
  • No pipes: `setNames(as.data.frame(t(iris[1:3, -5])), letters[1:3])` – zx8754 Feb 26 '16 at 16:28
  • Pipes aren't strictly necessary, but they are great for readability because they allow reading operations left to right, as described in the dplyr documentation: https://cran.r-project.org/web/packages/dplyr/dplyr.pdf – David M. Perlman Feb 27 '16 at 17:55
  • And thanks to everyone who told me about setNames, that definitely does the trick! Not sure why that didn't show up in any of my hours of google searching, but now this is all in one convenient place for future generations. – David M. Perlman Feb 27 '16 at 17:56
2

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
Keiku
  • 8,205
  • 4
  • 41
  • 44