Cambiar el nombre de varias columnas por nombre

Alguien debería haber preguntado esto, pero no pude encontrar una respuesta. Digamos que tengo:

x = data.frame(q=1,w=2,e=3, ...and many many columns...) 

¿Cuál es la forma más elegante de cambiar el nombre de un subconjunto arbitrario de columnas, cuya posición no conozco necesariamente, por otros nombres arbitrarios?

por ejemplo, decir que quiero cambiar el nombre "q" y "e" en "A" y "B" , ¿cuál es el código más elegante para hacer esto?

Obviamente, puedo hacer un bucle:

 oldnames = c("q","e") newnames = c("A","B") for(i in 1:2) names(x)[names(x) == oldnames[i]] = newnames[i] 

Pero me pregunto si hay una mejor manera? Tal vez usando algunos de los paquetes? ( plyr::rename etc.)

setnames del paquete data.table funcionará en data.frame s o data.table s

 library(data.table) d <- data.frame(a=1:2,b=2:3,d=4:5) setnames(d, old = c('a','d'), new = c('anew','dnew')) d # anew b dnew # 1 1 2 4 # 2 2 3 5 

Tenga en cuenta que los cambios se realizan por referencia, por lo que no se pueden copiar (¡incluso para data.frames!)

Con dplyr harías:

 library(dplyr) df = data.frame(q = 1, w = 2, e = 3) df %>% rename(A = q, B = e) # A w B #1 1 2 3 

O si desea usar vectores, como lo sugiere @ Jelena-bioinf:

 library(dplyr) df = data.frame(q = 1, w = 2, e = 3) oldnames = c("q","e") newnames = c("A","B") df %>% rename_at(vars(oldnames), ~ newnames) # A w B #1 1 2 3 

Otra solución para dataframes que no son demasiado grandes es (basándose en la respuesta @thelatemail):

 x <- data.frame(q=1,w=2,e=3) > x qwe 1 1 2 3 colnames(x) <- c("A","w","B") > x A w B 1 1 2 3 

Alternativamente, también puede usar:

 names(x) <- c("C","w","D") > x C w D 1 1 2 3 

Además, también puede cambiar el nombre de un subconjunto de los nombres de columna:

 names(x)[2:3] <- c("E","F") > x CEF 1 1 2 3 

Así que recientemente me encontré con esto, si no estás seguro de si las columnas existen y solo quieres cambiar el nombre de las que sí lo hacen:

 existing <- match(oldNames,names(x)) names(x)[na.omit(existing)] <- newNames[which(!is.na(existing))] 

Basándose en la respuesta de @ user3114046:

 x <- data.frame(q=1,w=2,e=3) x # qwe #1 1 2 3 names(x)[match(oldnames,names(x))] <- newnames x # A w B #1 1 2 3 

Esto no dependerá de un orden específico de columnas en el conjunto de datos x .

Esto cambiaría todas las apariciones de esas letras en todos los nombres:

  names(x) <- gsub("q", "A", gsub("e", "B", names(x) ) ) 

Esta es la forma más eficiente que he encontrado para cambiar el nombre de varias columnas mediante una combinación de purrr::set_names() y algunas operaciones de stringr .

 library(tidyverse) # Make a tibble with bad names data <- tibble( `Bad NameS 1` = letters[1:10], `bAd NameS 2` = rnorm(10) ) data # A tibble: 10 x 2 `Bad NameS 1` `bAd NameS 2`   1 a -0.840 2 b -1.56 3 c -0.625 4 d 0.506 5 e -1.52 6 f -0.212 7 g -1.50 8 h -1.53 9 i 0.420 10 j 0.957 # Use purrr::set_names() with annonymous function of stringr operations data %>% set_names(~ str_to_lower(.) %>% str_replace_all(" ", "_") %>% str_replace_all("bad", "good")) # A tibble: 10 x 2 good_names_1 good_names_2   1 a -0.840 2 b -1.56 3 c -0.625 4 d 0.506 5 e -1.52 6 f -0.212 7 g -1.50 8 h -1.53 9 i 0.420 10 j 0.957 
 names(x)[names(x) %in% c("q","e")]<-c("A","B") 

Puede obtener el nombre establecido, guardarlo como una lista y luego hacer un cambio de nombre en la cadena. Un buen ejemplo de esto es cuando realiza una transición larga a amplia en un conjunto de datos:

 names(labWide) Lab1 Lab10 Lab11 Lab12 Lab13 Lab14 Lab15 Lab16 1 35.75366 22.79493 30.32075 34.25637 30.66477 32.04059 24.46663 22.53063 nameVec <- names(labWide) nameVec <- gsub("Lab","LabLat",nameVec) names(labWide) <- nameVec "LabLat1" "LabLat10" "LabLat11" "LabLat12" "LabLat13" "LabLat14""LabLat15" "LabLat16" " 

Hay muchos tipos de respuestas, así que simplemente escribí la función para que pueda copiar / pegar.

 rename <- function(x, old_names, new_names) { stopifnot(length(old_names) == length(new_names)) # pull out the names that are actually in x old_nms <- old_names[old_names %in% names(x)] new_nms <- new_names[old_names %in% names(x)] # call out the column names that don't exist not_nms <- setdiff(old_names, old_nms) if(length(not_nms) > 0) { msg <- paste(paste(not_nms, collapse = ", "), "are not columns in the dataframe, so won't be renamed.") warning(msg) } # rename names(x)[names(x) %in% old_nms] <- new_nms x } x = data.frame(q = 1, w = 2, e = 3) rename(x, c("q", "e"), c("Q", "E")) Q w E 1 1 2 3 

Si una fila de los datos contiene los nombres a los que desea cambiar todas las columnas, puede hacer

 names(data) <- data[row,] 

Los data dados son su marco de data y la row es el número de fila que contiene los nuevos valores.

Luego puede eliminar la fila que contiene los nombres con

 data <- data[-row,] 

Sidenote, si desea concatenar una cadena para todos los nombres de columna, puede simplemente usar este código simple.

 colnames(df) <- paste("renamed_",colnames(df),sep="")