column change regex r rename dplyr

regex - change - rename r dplyr



R dplyr: renombra variables usando funciones de cadena (6)

(Pregunta un tanto relacionada: ingrese nuevos nombres de columna como cadena en la función de cambio de nombre de dplyr )

En el medio de una cadena dplyr ( %>% ), me gustaría reemplazar varios nombres de columnas con funciones de sus nombres antiguos (usando tolower o gsub , etc.)

library(tidyr); library(dplyr) data(iris) # This is what I want to do, but I''d like to use dplyr syntax names(iris) <- tolower( gsub("//.", "_", names(iris) ) ) glimpse(iris, 60) # Observations: 150 # Variables: # $ sepal_length (dbl) 5.1, 4.9, 4.7, 4.6, 5.0, 5.4, 4.6,... # $ sepal_width (dbl) 3.5, 3.0, 3.2, 3.1, 3.6, 3.9, 3.4,... # $ petal_length (dbl) 1.4, 1.4, 1.3, 1.5, 1.4, 1.7, 1.4,... # $ petal_width (dbl) 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3,... # $ species (fctr) setosa, setosa, setosa, setosa, s... # the rest of the chain: iris %>% gather(measurement, value, -species) %>% group_by(species,measurement) %>% summarise(avg_value = mean(value))

Veo ?rename toma el argumento replace como un named character vector, with new names as values, and old names as names.

Así que intenté:

iris %>% rename(replace=c(names(iris)=tolower( gsub("//.", "_", names(iris) ) ) ))

pero esto (a) devuelve Error: unexpected ''='' in iris %>% ... y (b) requiere referenciar el marco de datos de la operación anterior en la cadena, que en mi caso de uso real no pude hacer .

iris %>% rename(replace=c( )) %>% # ideally the fix would go here gather(measurement, value, -species) %>% group_by(species,measurement) %>% summarise(avg_value = mean(value)) # I realize I could mutate down here # instead, once the column names turn into values, # but that''s not the point # ---- Desired output looks like: ------- # Source: local data frame [12 x 3] # Groups: species # # species measurement avg_value # 1 setosa sepal_length 5.006 # 2 setosa sepal_width 3.428 # 3 setosa petal_length 1.462 # 4 setosa petal_width 0.246 # 5 versicolor sepal_length 5.936 # 6 versicolor sepal_width 2.770 # ... etc ....


Aquí hay una manera de evitar la sintaxis de rename algo torpe:

myris <- iris %>% setNames(tolower(gsub("//.","_",names(.))))


Creo que estás viendo la documentación de plyr::rename , no dplyr::rename . dplyr::rename algo como esto con dplyr::rename :

iris %>% rename_(.dots=setNames(names(.), tolower(gsub("//.", "_", names(.)))))


Mi intento elocuente utilizando base, stringr y dplyr:

EDITAR: la biblioteca (tidyverse) ahora incluye las tres bibliotecas.

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(".", "_")

Hago esto para construir funciones con tuberías.

my_read_fun <- function(x) { df <- read.csv(x) %>% names(df) %<>% tolower() %>% str_replace_all("_", ".") tempdf %<>% select(a, b, c, g) }


Para este caso particular [pero bastante común], la función ya se ha escrito en el paquete janitor :

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 ## . ... ... ... ... ...

así que todos juntos,

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


Tanto select() como select_all() se pueden usar para cambiar el nombre de las columnas.

Si solo desea cambiar el nombre de columnas específicas, puede utilizar 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 hace lo mismo, solo que sin tener que incluir 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() funciona en todas las columnas y puede tomar una función como un argumento:

iris %>% select_all(tolower) iris %>% select_all(~gsub("//.", "_", .))

o combinando los dos:

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


Esta es una respuesta muy tardía, en mayo de 2017.

A partir de dplyr 0.5.0.9004 , que pronto será 0.6.0, se han agregado al paquete muchas nuevas formas de renombrar columnas, compatibles con el operador de tubería maggritr %>% .

Esas funciones son:

  • cambiar el nombre de todos
  • renombrar_if
  • rename_at

Existen muchas formas diferentes de usar esas funciones, pero la que es relevante para su problema, utilizando el paquete stringr , es la siguiente:

df <- df %>% rename_all( funs( stringr::str_to_lower(.) %>% stringr::str_replace_all(., ''//.'', ''_'') ) )

Y así, continúe con la plomería :) (sin juego de palabras).