(Somewhat related question: Enter new column names as string in dplyr's rename function)
In the middle of a dplyr
chain (%>%
), I wou
I think you're looking at the documentation for plyr::rename
, not dplyr::rename
. You would do something like this with dplyr::rename
:
iris %>% rename_(.dots=setNames(names(.), tolower(gsub("\\.", "_", names(.)))))
For this particular [but fairly common] case, the function has already been written in the janitor package:
library(janitor)
iris %>% clean_names()
## 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
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
## . ... ... ... ... ...
so all together,
iris %>%
clean_names() %>%
gather(measurement, value, -species) %>%
group_by(species,measurement) %>%
summarise(avg_value = mean(value))
## Source: local data frame [12 x 3]
## Groups: species [?]
##
## species measurement avg_value
## <fctr> <chr> <dbl>
## 1 setosa petal_length 1.462
## 2 setosa petal_width 0.246
## 3 setosa sepal_length 5.006
## 4 setosa sepal_width 3.428
## 5 versicolor petal_length 4.260
## 6 versicolor petal_width 1.326
## 7 versicolor sepal_length 5.936
## 8 versicolor sepal_width 2.770
## 9 virginica petal_length 5.552
## 10 virginica petal_width 2.026
## 11 virginica sepal_length 6.588
## 12 virginica sepal_width 2.974
Both select()
and select_all()
can be used to rename columns.
If you wanted to rename only specific columns you can use select
:
iris %>%
select(sepal_length = Sepal.Length, sepal_width = Sepal.Width, everything()) %>%
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
rename
does the same thing, just without having to include everything()
:
iris %>%
rename(sepal_length = Sepal.Length, sepal_width = Sepal.Width) %>%
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
select_all()
works on all columns and can take a function as an argument:
iris %>%
select_all(tolower)
iris %>%
select_all(~gsub("\\.", "_", .))
or combining the two:
iris %>%
select_all(~gsub("\\.", "_", 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
Here's a way around the somewhat awkward rename
syntax:
myris <- iris %>% setNames(tolower(gsub("\\.","_",names(.))))
My eloquent attempt using base, stringr and dplyr:
EDIT: library(tidyverse) now includes all three libraries.
library(tidyverse)
library(maggritr) # Though in tidyverse to use %>% pipe you need to call it
# library(dplyr)
# library(stringr)
# library(maggritr)
names(iris) %<>% # pipes so that changes are apply the changes back
tolower() %>%
str_replace_all(".", "_")
I do this for building functions with piping.
my_read_fun <- function(x) {
df <- read.csv(x) %>%
names(df) %<>%
tolower() %>%
str_replace_all("_", ".")
tempdf %<>%
select(a, b, c, g)
}
In case you don't want to write the regular expressions yourself, you could use
janitor::make_clean_names()
which has some nice defaults orjanitor::clean_names()
which does the same as make_clean_names()
, but works directly on data frames.Invoking them inside of a pipeline should be straightforward.
library(magrittr)
library(snakecase)
iris %>% setNames(to_snake_case(names(.)))
iris %>% tibble::as_tibble(.name_repair = to_snake_case)
iris %>% purrr::set_names(to_snake_case)
iris %>% dplyr::rename_all(to_snake_case)
iris %>% janitor::clean_names()