data.table (II): agregaciones

Sigo con mi lacónica serie sobre data.table.

La protagonista:

frases[sample(1:nrow(frases), 3),]
#pos.es pos.en length.es length.en en        es frase          tfe      qjilm          num
#1:     15     43        72        72  i        de  2632 4.881416e-02 0.01369863 6.686871e-04
#2:     33     48        46        48  X    países  5321 2.726146e-06 0.02040816 5.563563e-08
#3:      2     35        53        66 in preguntar  4582 2.424379e-08 0.01492537 3.618476e-10
dim(frases)
#[1] 6340091      10

El tiempo:

system.time({
  setkey(frases, "frase", "es")
  denominadores <- frases[, sum(num), by = key(frases)]
  setnames(denominadores, c("frase", "es", "den") )
  frases <- merge(frases, denominadores)
  frases$delta <- frases$num / frases$den
})
#user  system elapsed 
#5.628   0.208   5.841 

En particular,

system.time( denominadores <- frases[, sum(num), by = key(frases)] )
#user  system elapsed 
#0.228   0.000   0.228 

Increíble, ¿no?

6 comentarios sobre “data.table (II): agregaciones

  1. Xavier de Pedro 9 mayo, 2013 10:16

    ¿Y has probado cuanta diferencia hay con aggregate? (yo hace unas semanas usaba ftable para agregar resultados, pero se me volvió lento al usar data frames grandes… como fuente de datos para el ftable. Pasé del ftable, y agregré con aggregate me fue mejor (siento no tener los datos de rendimiento a mano , hablo de memoria)

  2. datanalytics 9 mayo, 2013 12:34

    @Xavier de Pedro Pues debí haber puesto la comparación (igual lo hago estos días). Lo que te puedo decir es que tenía mi proceso original implementado con merges y aggregates tradicionales y tras reimplementarlo con data.table… se hizo la luz.

    Fíjate que aggregate usa lapply internamente. La ventaja de data.table (algo de lo que no he hablado en la entrada) es que indexa los dataframes (más bien, los ordena por las variables del índice) y que aprovecha ese índice tanto para cruzar como para agregar. La ventaja de data.table tiene que ser sustancial con respecto a aggregate con tablas grandes.

  3. datanalytics 9 mayo, 2013 18:27

    @Oscar Perpiñán Lamigueiro Sí, cierto. Y yo había visto algunas otras comparaciones (e incluso había hecho algunas en el pasado) en las que data.table no brillaba demasiado. Posiblemente porque las tablas sobre las que se realizaban no eran lo suficientemente grandes.

    Realmente hace falta que las tablas sean grandes para que valga la pena asumir la complejidad adicional que supone usar data.table. Y que compense el «overhead» que puede implicar usar estructuras de datos más complejas. Pero una vez que traspasas el umbral del millón de registros, la verdad, no hay color.

  4. dcb 14 mayo, 2013 10:29

    muy buena idea el escribir sobre data.table; efectivamente es un excelente paquete para gestión de datos relativamente grandes . Te animo a que pruebes/escribas acerca de la nueva función fread de data.table alternativa al clásico read.table que permite cargar los datos directamente a un data.table sin pasar por data.frame de una manera mucho más rápida (y cómoda incluso) que con otros métodos ( http://stackoverflow.com/questions/1727772/quickly-reading-very-large-tables-as-dataframes-in-r ) o al operador := que añade y transforma columnas por referencia en vez de hacer copias.

Los comentarios están desabilitados.