¿Cuándo debo usar el operador: = en data.table?

88

data.tablelos objetos ahora tienen un operador: =. ¿Qué diferencia a este operador de todos los demás operadores de asignación? Además, ¿cuáles son sus usos, cuánto más rápido es y cuándo debe evitarse?

Ari B. Friedman
fuente

Respuestas:

94

Aquí hay un ejemplo que muestra 10 minutos reducidos a 1 segundo (de NEWS en la página de inicio ). Es como realizar una subasignación a a, data.framepero no copia toda la tabla cada vez.

m = matrix(1,nrow=100000,ncol=100)
DF = as.data.frame(m)
DT = as.data.table(m)

system.time(for (i in 1:1000) DF[i,1] <- i)
     user  system elapsed 
  287.062 302.627 591.984 

system.time(for (i in 1:1000) DT[i,V1:=i])
     user  system elapsed 
    1.148   0.000   1.158     ( 511 times faster )

Poner el :=de jesa manera permite más expresiones idiomáticas:

DT["a",done:=TRUE]   # binary search for group 'a' and set a flag
DT[,newcol:=42]      # add a new column by reference (no copy of existing data)
DT[,col:=NULL]       # remove a column by reference

y:

DT[,newcol:=sum(v),by=group]  # like a fast transform() by group

¡No puedo pensar en ninguna razón para evitarlo :=! Aparte de, dentro de un forbucle. Como :=aparece en el interior DT[...], viene con la pequeña sobrecarga del [.data.tablemétodo; por ejemplo, S3 envío y comprobación de la presencia y tipo de argumentos tales como i, by, nomatchetc. Así que para el interior de forlos bucles, hay una sobrecarga baja, versión directa de :=llamada set. Consulte ?setpara obtener más detalles y ejemplos. Las desventajas de setincluir que ideben ser números de fila (sin búsqueda binaria) y no se pueden combinar con by. Hacer esas restricciones setpuede reducir los gastos generales drásticamente.

system.time(for (i in 1:1000) set(DT,i,"V1",i))
     user  system elapsed 
    0.016   0.000   0.018
Matt Dowle
fuente
26
Gracias por desarrollar este paquete. Tengo la sensación de que voy a revisar mucho de mi código para usar este paquete.
Iterador
1
En el chat me pidieron que me preguntara / respondiera yo mismo (lo que aparentemente se recomienda ), esa pregunta está aquí
Matt Dowle
4
@MatthewDowle ¿Desea incluir una explicación de cuándo no usar: = y usar set () en su lugar?
Ari B. Friedman
2
@MatthewDowle Volvería a hacer +1 si pudiera.
Ari B. Friedman
3
@jabberwocky No hay problema. set(DT, i, "V1", i)establece la "V1"columna while set(DT, i, colVar, i)establece el nombre de la columna contenido en la colVarvariable (por ejemplo, si colVar = "V1"se hizo antes). Las comillas indican tomar el nombre de la columna literalmente en lugar de buscar la variable.
Matt Dowle