recodificar - Cambiar el nombre de varias columnas por nombre
recodificar variables en r (12)
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.)
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
# q w e
#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
.
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
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`
<chr> <dbl>
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
<chr> <dbl>
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
Esto cambiaría todas las apariciones de esas letras en todos los nombres:
names(x) <- gsub("q", "A", gsub("e", "B", names(x) ) )
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
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
q w e
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
C E F
1 1 2 3
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" "
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="")
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!)
names(x)[names(x) %in% c("q","e")]<-c("A","B")