r performance group-by data.table

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 . Cuando i soy una tabla de datos, DT[i,j,by=.EACHI] evalúa j para los grupos de DT que 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?