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