2012-02-14 17 views
29

Quiero cambiar el nombre de algunas columnas aleatorias de un gran marco de datos y quiero utilizar los nombres de las columnas actuales, no los índices. Los índices de columna pueden cambiar si agrego o quito columnas a los datos, así que me imagino que usar los nombres de columna existentes es una solución más estable. Esto es lo que tengo ahora:Columnas con nombre Cambio de nombre

mydf = merge(df.1, df.2) 
colnames(mydf)[which(colnames(mydf) == "MyName.1")] = "MyNewName" 

¿Puedo simplificar el código, ya sea el merge() llamada original o simplemente la segunda línea? "MyName.1" es en realidad el resultado de un xts merge de dos objetos xts diferentes.

+0

¿Puede dar un pequeño conjunto de datos reproducibles con la salida deseada? – Dason

+0

¡No necesitas el 'que' hay! R acepta booleano en el operador []. 'colnames (mydf) [colnames (mydf) ==" MyName.1 "] =" MyNewName "' debería funcionar! –

+1

'names (mydf) [names (mydf) ==" MyName.1 "] =" MyNewName "' ... aproximadamente 13 o menos caracteres más cortos. Aunque, es posible que desee reemplazar un vector en ese caso, use% en% en lugar de ==. –

Respuesta

21
names(mydf)[names(mydf) == "MyName.1"] = "MyNewName" # 13 characters shorter. 

Aunque, es posible que desee reemplazar un vector con el tiempo. En ese caso, utilice %in% en lugar de == y establecer MyName.1 como un vector de longitud igual a MyNewName

4
names(mydf) <- sub("MyName\\.1", "MyNewName", names(mydf)) 

Esto generalizar mejor a una estrategia de cambio de nombre múltiple si se pone un tallo como un patrón de ser reemplazado utilizando gsub en lugar de sub.

+0

Gracias, esto me puso en el camino correcto. Ahora estoy haciendo: nombres (df) [grep (". 1", nombres (df))] = c ("AName.Col1", "AName.Col2", "AName.Col3") –

115

El problema con el cambio de nombres de columna de un data.frame es que, casi increíblemente, se copia todo el data.frame. Incluso cuando está en .GlobalEnv y ninguna otra variable lo señala.

data.table package tiene una función setnames() que cambia los nombres de las columnas por referencia sin copiar todo el conjunto de datos. data.table es diferente en que no copia en escritura, que puede ser muy importante para grandes conjuntos de datos. (Usted ha dicho tu conjunto de datos era grande.)

require(data.table) 
setnames(DT,"MyName.1","MyNewName") 
?setnames 
+4

Heh. Ese es un problema con hacer casi cualquier cosa con un 'data.frame'. Uno pensaría que simplemente cambiar los niveles de los factores también sería rápido, pero no lo es. (Estoy seguro de que todos ustedes lo saben). –

+0

@DWin. Hola. Creo que 'setattrib()' en 'data.table' podría cambiar los niveles de una columna por referencia (también en' data.frame'). Obviamente debe hacerse con cuidado. Podría haber una nueva función 'setlevels()' que cambiaría uno o más niveles (con la misma interfaz que 'setnames()')? Por cierto, ': =' ya agrega nuevos niveles de factor por referencia, lo cual es complicado en la base. Hay un poco de código C detrás de eso. –

23

plyr tiene una función de cambio de nombre para este propósito:

library(plyr) 
mydf <- rename(mydf, c("MyName.1" = "MyNewName")) 
+3

Esta función también se incluye ahora en el paquete 'dplyr' también. –

Cuestiones relacionadas