r join reference copy data.table

data.table join y luego agrega columnas a data.frame existente sin volver a copiar



reference copy (2)

Tengo dos data.tables , X (3m filas por ~ 500 columnas) e Y (100 filas por dos columnas).

set.seed(1) X <- data.table( a=letters, b=letters, c=letters, g=sample(c(1:5,7),length(letters),replace=TRUE), key="g" ) Y <- data.table( z=runif(6), g=1:6, key="g" )

Quiero hacer una combinación externa izquierda en X, lo que puedo hacer con Y[X] gracias a:

¿Por qué X [Y] se une a data.tables no permite una combinación externa completa, o una combinación izquierda?

Pero quiero agregar la nueva columna a X sin copiar X (ya que es enorme).

Obviamente, algo como X <- Y[X] funciona, pero a menos que data.table sea ​​mucho más inteligente de lo que le doy crédito (y le doy crédito por una gran cantidad de desviaciones!), Creo que esto copia la totalidad de X .

X[ , z:= Y[X,z]$z ] funciona, pero es kludgy y no se adapta bien a más de una columna.

¿Cómo almaceno los resultados de una combinación de nuevo en la tabla de datos retenidos de manera eficiente (tanto en términos de copias como en términos de tiempo de programación)?


Como una adición a la respuesta anterior, también puede hacer ( v1.9.6+ ):

require(data.table) # v1.9.6+ X[Y, (colNames) := mget(paste0("i.", colNames))]

donde colNames es un vector de caracteres que enumera las columnas que desea de Y Esto le permite seleccionar columnas de manera eficiente para agregarlas (defina los names(Y) de los names(Y) de un subconjunto de names(Y) ) en el caso de que agregue muchas columnas.

Además, puede combinarlo con el nuevo argumento on= (de v1.9.6+ ) como:

# ad-hoc joins using ''on='' instead of setting keys require(data.table) # v1.9.6+ X[Y, (colNames) := mget(paste0("i.", colNames)), on = "g"]

Crédito a akrun por la (colNames) := mget(colNames) aquí: Actualizar filas del marco de datos en R.


Esto es fácil de hacer:

X[Y, z := i.z]

Funciona porque la única diferencia entre Y[X] y X[Y] aquí es que cuando algunos elementos no están en Y , en cuyo caso probablemente querría que z fuera NA , lo que hará exactamente la asignación anterior.

También funcionaría igual de bien para muchas variables:

X[Y, `:=`(z1 = i.z1, z2 = i.z2, ...)]

Dado que requiere la operación Y[X] , puede agregar el argumento nomatch=0 (como @mnel señala) para no obtener NA para aquellos en los que X no contiene los valores clave de Y. Eso es:

X[Y, z := i.z, nomatch=0]

De las NOTICIAS para data.table

********************************************** ** ** ** CHANGES IN DATA.TABLE VERSION 1.7.10 ** ** ** **********************************************

NUEVAS CARACTERÍSTICAS

o The prefix i. can now be used in j to refer to join inherited columns of i that are otherwise masked by columns in x with the same name.