r - .EACHI en data.table?
performance group-by (1)
He agregado esto a la lista here . Y con suerte podremos cumplir lo planeado.
La razón más probable es que by=.EACHI sea una característica reciente (desde 1.9.4), pero lo que hace no es . Dejame explicarte con un ejemplo. Supongamos que tenemos dos data.tables X e Y :
X = data.table(x = c(1,1,1,2,2,5,6), y = 1:7, key = "x")
Y = data.table(x = c(2,6), z = letters[2:1], key = "x")
Sabemos que podemos unirnos haciendo X[Y] . esto es similar a una operación de subconjunto , pero usando data.tables (en lugar de enteros / nombres de fila o valores lógicos). Para cada fila en Y , tomando las columnas clave de Y , encuentra y devuelve las correspondientes filas coincidentes en las columnas clave de X (+ columnas en Y ).
X[Y]
# x y z
# 1: 2 4 b
# 2: 2 5 b
# 3: 6 7 a
Ahora digamos que nos gustaría, para cada fila de las columnas clave de Y (aquí solo una columna de clave), nos gustaría obtener el recuento de coincidencias en X En versiones de data.table <1.9.4 , podemos hacer esto simplemente especificando .N en j siguiente manera:
# < 1.9.4
X[Y, .N]
# x N
# 1: 2 2
# 2: 6 1
Lo que esto hace implícitamente es, en presencia de j , evaluar la j-expression en cada resultado coincidente de X (que corresponde a la fila en Y ). Esto fue llamado by-without-by o implicit-by , porque es como si hubiera un oculto por.
El problema es que esto siempre llevará a cabo una operación by . Entonces, si quisiéramos saber el número de filas después de una unión, entonces tendríamos que hacer: X[Y][ .N] (o simplemente nrow(X[Y]) en este caso). Es decir, no podemos tener la expresión j en la misma llamada si no queremos un by-without-by . Como resultado, cuando hicimos, por ejemplo, X[Y, list(z)] , evaluó la list(z) usando by-without-by y, by-without-by lo tanto, fue un poco más lento.
Además, los usuarios de data.table solicitaron que esto sea explícito ; vea this y this para obtener más contexto.
Por lo tanto, se agregó by=.EACHI . Ahora, cuando lo hacemos:
X[Y, .N]
# [1] 3
hace lo que debe hacer (evita confusiones). Devuelve el número de filas resultantes de la unión.
Y,
X[Y, .N, by=.EACHI]
evalúa j expression en las filas coincidentes para cada fila en Y (correspondiente al valor de las columnas clave Y aquí). Sería más fácil ver esto usando which=TRUE .
X[.(2), which=TRUE] # [1] 4 5
X[.(6), which=TRUE] # [1] 7
Si ejecutamos .N para cada uno, deberíamos obtener 2,1.
X[Y, .N, by=.EACHI]
# x N
# 1: 2 2
# 2: 6 1
Entonces ahora tenemos ambas funcionalidades. Espero que esto ayude.
Parece que no puedo encontrar ninguna documentación sobre qué exactamente .EACHI hace en data.table . Veo una breve mención de esto en la documentación:
La agregación para un subconjunto de grupos conocidos es particularmente eficiente al pasar esos grupos en iy configurar
by=.EACHI. Cuandoisoy una tabla de datos,DT[i,j,by=.EACHI]evalúajpara los grupos deDTque se une cada fila. Llamamos a esta agrupación por cada i.
¿Pero qué significan "grupos" en el contexto de DT ? ¿Un grupo está determinado por la clave que se establece en DT ? ¿El grupo es cada fila distinta que usa todas las columnas como clave? Entiendo completamente cómo ejecutar algo como DT[i,j,by=my_grouping_variable] pero estoy confundido sobre cómo .EACHI funcionaría. ¿Podría alguien explicar por favor?