2012-06-14 8 views
23

Tengo data.frame en R con 19 millones de filas y 90 columnas. Tengo muchos RAM de repuesto y ciclos de CPU. Parece que el cambio de un solo nombre de columna en esta trama de datos es una operación muy intensa para R.¿Por qué el cambio de un nombre de columna lleva mucho tiempo con un gran data.frame?

system.time(colnames(my.df)[1] <- "foo") 
    user system elapsed 
356.88 16.54 373.39 

¿Por qué es esto así? ¿Cada fila almacena el nombre de la columna de alguna manera? ¿Esto está creando un marco de datos completamente nuevo? Parece que esta operación debería completarse en un tiempo insignificante. No veo nada obvio en el R manual entry.

Estoy ejecutando la compilación 7600 de R (64 bits) en Windows 7, y en mi espacio de trabajo actual, la configuración de colnames en un pequeño data.frame toma '0' tiempo según system.time().

Editar: Estoy al tanto de la posibilidad de utilizar data.table, y, sinceramente, puedo esperar 5 minutos para que se complete el cambio mientras tomo un té. Lo que me interesa es ¿Qué está pasando y por qué?

+0

Curiosamente, estaba leyendo acerca de esto. Creo que en realidad podría estar copiando el df _twice_. Si está utilizando 2.15.0, intente instalar y cargar el paquete ** dataframe ** y vea si eso ayuda. – joran

+5

Matthew Dowle explica esto muy bien [aquí] (http://stackoverflow.com/questions/10655438/rename-one-named-column-in-r/10655997#10655997) y proporciona una solución con el paquete 'data.table' . – Chase

+0

Gracias, ya utilizo 'data.table' bastante (¡y estoy en deuda con Matthew Dowle por sacarme de las situaciones difíciles!) - Aquí estaba después de una explicación de lo que está sucediendo ... e idealmente por qué. ¿La respuesta es realmente solo "data.frame está mal codificado"? – Ina

Respuesta

21

Como han mencionado varios comentaristas, cambiar el nombre de las columnas del marco de datos es lenta, debido a que (dependiendo de cómo lo hace) que tiene entre 1 y 4 copias de toda la hoja.de.datos. Aquí, desde data.table 's página ?setkey ayuda, es la mejor manera de demostrar este comportamiento que he visto:

DF = data.frame(a=1:2,b=3:4)  # base data.frame to demo copies 
try(tracemem(DF))     # try() for non-Windows where R is 
            # faster without memory profiling 
colnames(DF)[1] <- "A"    # 4 copies of entire object 
names(DF)[1] <- "A"    # 3 copies of entire object 
names(DF) <- c("A", "b")   # 1 copy of entire object 
`names<-`(DF,c("A","b"))   # 1 copy of entire object 
x=`names<-`(DF,c("A","b"))   # still 1 copy (so not print method) 
# What if DF is large, say 10GB in RAM. Copy 10GB just to change a column name? 

A (inicio) entender por qué se hacen las cosas de esta manera, es probable que tengas para profundizar en algunas de las discusiones relacionadas en R-devel. Aquí hay un par: R-devel: speeding up perception y R-devel: Confused about NAMES

Mi lectura impresionista de esos hilos es que:

  1. Al menos una copia se realiza de modo que las modificaciones que se pueden 'probaron' antes de sobrescribir el original. Por lo tanto, si algo está mal con el valor a ser reasignado, [<-.data.frame o names<- pueden 'retroceder' y entregar un mensaje de error sin haber hecho ningún daño al objeto original.

  2. Varios miembros de R-core no están completamente satisfechos con el funcionamiento de las cosas en este momento. Varias personas explican que en algunos casos "R pierde la pista"; Luke Tierney indica que ha intentado algunas modificaciones relacionadas con esta copia en el pasado "en algunos casos y siempre tuvo que retroceder"; y Simon Urbanek insinúa que "puede haber algunas cosas por venir, también"

(Como ya he dicho, sin embargo, eso es sólo impresionista: Yo simplemente no soy capaz de seguir una conversación completa sobre los detalles de R de internos)


también es pertinente, en caso de que no lo ha visto, así es como algo así como names(z)[3] <- "c2" "realmente" funciona:!

# From ?names<- 
z <- "names<-"(z, "[<-"(names(z), 3, "c2")) 

Nota: Gran parte de esta respuesta proviene de la respuesta de Matthew Dowle al this other question. (Pensé que valía la pena colocarlo aquí, y darle más exposición, ya que es tan relevante para su propia pregunta).

+1

++ para analizar los hilos R-devel, me estaba costando pasar por alto esas conversaciones. – Ina

Cuestiones relacionadas