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 и не масштабируется до более чем одного столбца.
Как сохранить результаты слияния обратно в сохраненную таблицу данных в эффективном (как с точки зрения копирования, так и с точки зрения времени программиста)?
Ответы
Ответ 1
Это легко сделать:
X[Y, z := i.z]
Это работает, потому что единственное различие между 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 := i.z, 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.
Ответ 2
В дополнение к приведенному выше ответу вы также можете сделать (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 для стратегии (colNames) := mget(colNames)
здесь: Обновить строки фрейма данных в R.