Как объединить два больших набора данных при генерации нового столбца с другим значением повторения в r

У меня есть вопрос, который сводит меня с ума и действительно нуждается в вашей помощи. Упрощенный вопрос:

d1<-data.table(v1=c("a","b","c","d","d","b","a","c","a","d","b","a"),
                    v2=(seq(1:12)),V3=rep(1:4,times=3))

d2<-data.table(v1=c("a","b","c","d"),v3=c(3,2,1,4),v4=c("y","x","t","e"))

Это даст два набора данных:

    D1:     
    v1 v2 V3
 1:  a  1  1
 2:  b  2  2
 3:  c  3  3
 4:  d  4  4
 5:  d  5  1
 6:  b  6  2
 7:  a  7  3
 8:  c  8  4
 9:  a  9  1
10:  d 10  2
11:  b 11  3
12:  a 12  4

> d2
   v1 v3 v4
1:  a  3  y
2:  b  2  x
3:  c  1  t
4:  d  4  e

Как вы могли видеть, элементы в v1 и v3 одинаковы. Теперь я хочу объединить оба набора данных, создав новый столбец в D1, который возвращает значение V4 в d2, которое соответствует обоим индексам v1 и v3, надеюсь, что я мог бы получить вывод, выглядящий следующим образом:

>

 d3
    v1 v2 V3 V4
 1:  a  1  1 na
 2:  b  2  2  x
 3:  c  3  3 na
 4:  d  4  4  e
 5:  d  5  1 na
 6:  b  6  2  x
 7:  a  7  3  y
 8:  c  8  4 na
 9:  a  9  1 na
10:  d 10  2 na
11:  b 11  3 na
12:  a 12  4 na

Размер фактических данных, которые я использую, относительно велик. Это что-то вроде совлокальных 113 МБ данных с 23 МБ. Я попытался использовать для цикла, чтобы сделать эту проблему, потому что данные так долго, для завершения задачи требуется много времени. Я также пробовал merge и sqldf, но оба они не смогли завершить работу. Не могли бы вы помочь мне с этой проблемой? Большое спасибо!

Ответ 1

Я бы сделал это вот так:

setkey(d1, v1, V3) 
d1[d2, v4 := v4][]
  • Для соединения формы x[i] необходимо установить ключ для x. i может иметь или не иметь набор ключей. Поэтому мы устанавливаем для d1 ключ для столбцов v1 и V3.

  • Далее мы выполняем объединение d1[d2], которое для каждой строки d2 находит строки, которые соответствуют столбцам ключа d1, и возвращает результат объединения. Мы точно не ищем этот результат. Мы хотели бы добавить новый столбец, где каждая соответствующая строка получает значение от d2 v4 и в противном случае NA. Для этого мы используем подзадачу data.table по ссылочным функциям. При подключении i to x мы все равно можем предоставить выражение в j и ссылаться на столбцы i. Вы также можете ссылаться на них как i.v4 (обычно используется, если есть столбцы с одинаковыми именами как в x, так и i).

  • := добавляет/обновляет столбец по ссылке. LHS := - это имя столбца, которое мы хотим создать здесь, а RHS v4 - это значение, которое мы хотим присвоить (здесь, это столбец от d2). Поэтому для каждой соответствующей строки мы назначаем d2 v4 на d1 новый столбец (который мы называем) v4 по ссылке (на месте, что означает, что копия не создается), и те строки без совпадений получат значение по умолчанию NA.

  • Последний [] предназначен для печати вывода на экран, поскольку := возвращает результат невидимо.

Надеюсь, это поможет понять, что происходит здесь.