Подтвердить что ты не робот

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 и не масштабируется до более чем одного столбца.

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

4b9b3361

Ответ 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.