Data.table: GForce también debería poder trabajar con `: =`.

Creado en 29 oct. 2015  ·  3Comentarios  ·  Fuente: Rdatatable/data.table

GForce enhancement performance

Comentario más útil

Solo quería enfatizar que habilitar esto puede permitir usar GForce de manera efectiva para expresiones complejas, aunque con algo de trabajo. Por ejemplo, muestro en esta publicación cómo habilitarlo para:

slope <- function(x, y) {
  x_ux <- x - mean(x)
  uy <- mean(y)
  sum(x_ux * (y - uy)) / sum(x_ux ^ 2)
}

Haciendo:

DT <- data.table(grp, x, y)
setkey(DT, grp)
DTsum <- DT[, .(ux=mean(x), uy=mean(y)), keyby=grp]
DT[DTsum, `:=`(x_ux=x - ux, y_uy=y - uy)]
DT[, `:=`(x_ux.y_uy=x_ux * y_uy, x_ux2=x_ux^2)]
DTsum <- DT[, .(x_ux.y_uy=sum(x_ux.y_uy), x_ux2=sum(x_ux2)), keyby=grp]
res.slope.dt2 <- DTsum[, .(grp, V1=x_ux.y_uy / x_ux2)]

Mientras que si GForce fuera compatible con := , podríamos hacer:

DT <- data.table(grp, x, y)
DT[, `:=`(ux=mean(x), uy=mean(y)), keyby=grp]
DT[, `:=`(x_ux=x - ux, y_uy=y - uy)]
DT[, `:=`(x_ux.y_uy=x_ux * y_uy, x_ux2=x_ux^2)]
DTsum <- DT[, .(x_ux.y_uy=sum(x_ux.y_uy), x_ux2=sum(x_ux2)), keyby=grp]
res.slope.dt3 <- DTsum[, .(grp, x_ux.y_uy/x_ux2)]

Que parece más limpio y debería ser más rápido.

Todos 3 comentarios

Me encontré con esto hoy mirando una pregunta sobre SO :

actions = data.table(User_id = c("Carl","Carl","Carl","Lisa","Moe"),
                     category = c(1,1,2,2,1),
                     value= c(10,20,30,40,50))
users = actions[, other_var := 1, by=User_id]

# verbose says: the following is not optimized
users[, value_one := 0 ]
users[actions[category==1], value_one := sum(value), on="User_id", by=.EACHI, verbose=TRUE]

# verbose says: the following is optimized
rbind( 
    actions[category==1], 
    unique(actions[,"User_id", with=FALSE])[, value := 0 ],
fill=TRUE)[, sum(value), by=User_id, verbose=TRUE]

Para mí, la primera forma parece idiomática, considerando que la variable debe terminar en users al final.

Otro: https://stackoverflow.com/a/47338118/ (gtail)

Otro https://stackoverflow.com/a/51569126/ debería hacer DT[, mx := max(pt), by=Subject][, diff := mx - pt][] supongo

Otro, específicamente interesado en el rendimiento de la memoria: https://stackoverflow.com/q/52189712 "semántica de referencia de data.table: uso de memoria de iterar a través de todas las columnas"

Otro, quiere scale / degradar múltiples variables: https://stackoverflow.com/q/52528123

Otro tomando el máximo por grupo con una condición de subconjunto y agregando con: = (ver la respuesta de akrun) https://stackoverflow.com/a/54911855/ también está relacionado con la parte ya completada de # 971

Solo quería enfatizar que habilitar esto puede permitir usar GForce de manera efectiva para expresiones complejas, aunque con algo de trabajo. Por ejemplo, muestro en esta publicación cómo habilitarlo para:

slope <- function(x, y) {
  x_ux <- x - mean(x)
  uy <- mean(y)
  sum(x_ux * (y - uy)) / sum(x_ux ^ 2)
}

Haciendo:

DT <- data.table(grp, x, y)
setkey(DT, grp)
DTsum <- DT[, .(ux=mean(x), uy=mean(y)), keyby=grp]
DT[DTsum, `:=`(x_ux=x - ux, y_uy=y - uy)]
DT[, `:=`(x_ux.y_uy=x_ux * y_uy, x_ux2=x_ux^2)]
DTsum <- DT[, .(x_ux.y_uy=sum(x_ux.y_uy), x_ux2=sum(x_ux2)), keyby=grp]
res.slope.dt2 <- DTsum[, .(grp, V1=x_ux.y_uy / x_ux2)]

Mientras que si GForce fuera compatible con := , podríamos hacer:

DT <- data.table(grp, x, y)
DT[, `:=`(ux=mean(x), uy=mean(y)), keyby=grp]
DT[, `:=`(x_ux=x - ux, y_uy=y - uy)]
DT[, `:=`(x_ux.y_uy=x_ux * y_uy, x_ux2=x_ux^2)]
DTsum <- DT[, .(x_ux.y_uy=sum(x_ux.y_uy), x_ux2=sum(x_ux2)), keyby=grp]
res.slope.dt3 <- DTsum[, .(grp, x_ux.y_uy/x_ux2)]

Que parece más limpio y debería ser más rápido.

Las conversaciones con @MichaelChirico me hacen darme cuenta de que un primo muy cercano a este problema es:

>   DT <- data.table(x, y, grp)
>   DT[, .(x, mean(x)), keyby=grp]
Detected that j uses these columns: x 
Finding groups using forderv ... 1.049s elapsed (0.946s cpu) 
Finding group sizes from the positions (can be avoided to save RAM) ... 0.011s elapsed (0.011s cpu) 
lapply optimization is on, j unchanged as 'list(x, mean(x))'
GForce is on, left j unchanged
Old mean optimization changed j from 'list(x, mean(x))' to 'list(x, .External(Cfastmean, x, FALSE))'
Making each group and running j (GForce FALSE) ... 
  collecting discontiguous groups took 1.293s for 999953 groups
  eval(j) took 1.860s for 999953 calls
5.517s elapsed (3.862s cpu) 
              grp         x        V2
       1:       1 0.2151365 0.5512966
       2:       1 0.5358256 0.5512966
       3:       1 0.8496598 0.5512966
       4:       1 0.8480730 0.5512966
       5:       1 0.3464458 0.5512966
      ---                            
 9999996: 1000000 0.2601940 0.5474986
 9999997: 1000000 0.7940921 0.5474986
 9999998: 1000000 0.3825493 0.5474986
 9999999: 1000000 0.1786861 0.5474986
10000000: 1000000 0.9179119 0.5474986

Enlace cruzado a # 523.

¿Fue útil esta página
0 / 5 - 0 calificaciones