data.table join, затем добавьте столбцы в существующий файл data.frame без повторной копии

У меня есть два data.tables , X (3m строк на ~ 500 столбцов) и Y (100 строк на два столбца).

 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" ) 

Я хочу сделать левое внешнее соединение на X, что я могу сделать Y[X] благодаря:

Почему X [Y] присоединяется к data.tables, не допускает полного внешнего соединения или левого соединения?

Но я хочу добавить новый столбец в X без копирования X (поскольку он огромен).

Очевидно, что что-то вроде X <- Y[X] работает, но если data.table намного умнее, чем я даю ему кредит (и я даю ему кредит за довольно много коварства!), Я считаю, что это копирует весь X ,

X[ , z:= Y[X,z]$z ] работает, но является kludgy и не масштабируется до более чем одного столбца.

Как сохранить результаты слияния обратно в сохраненную таблицу данных в эффективном (как с точки зрения копирования, так и с точки зрения времени программиста)?

Это легко сделать:

 X[Y, z := iz] 

Это работает, потому что единственная разница между Y[X] и X[Y] здесь, когда некоторые элементы не находятся в Y , и в этом случае, предположительно, вы хотите, чтобы z было NA , которое будет выполнять указанное выше назначение.

Он также будет работать так же хорошо для многих переменных:

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

Поскольку вам нужна операция Y[X] , вы можете добавить аргумент nomatch=0 (как указывает @mnel), чтобы не получить NA для тех, где X не содержит значений ключа из Y. То есть:

 X[Y, z := iz, nomatch=0] 

Из НОВОСТИ для data.table

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

НОВЫЕ ВОЗМОЖНОСТИ

 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. 

В дополнение к приведенному выше ответу вы также можете сделать ( v1.9.6+ ):

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

где colNames – вектор символов, в котором перечислены столбцы, которые вы хотите от Y Это позволяет эффективно выбирать столбцы для добавления (определять colNames подмножеством names(Y) ) в случае, если вы добавляете много столбцов.

Кроме того, вы можете объединить его с новым аргументом on= (от v1.9.6+ ) как:

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

Подпишитесь на akrun для страtagsи (colNames) := mget(colNames) здесь: обновите строки кадра данных в R.

Давайте будем гением компьютера.