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

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 astucia!), Creo que esto copia la totalidad de X .

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

¿Cómo guardo los resultados de una fusión en la tabla de datos retenidos de una manera eficiente (tanto en términos de copias como en términos de tiempo del progtwigdor)?

    Esto es fácil de hacer:

     X[Y, z := iz] 

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

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

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

    Como necesita la operación Y[X] , puede agregar el argumento nomatch=0 (como @mnel señala) para no obtener NA para aquellos donde X no contiene los valores clave de Y. Es decir:

     X[Y, z := iz, 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. 

    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 de manera eficiente columnas para agregar (definir colNames de un subconjunto de names(Y) ) en el caso de que esté agregando 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 para la (colNames) := mget(colNames) aquí: Actualizar filas de dataframe en R.