Как объединить два кадра данных, используя несколько столбцов в качестве ключа?

Скажем, у меня есть следующие данные:

DF1 <- data.frame("A" = rep(c("A","B"), 18),
                  "B" = rep(c("C","D","E"), 12),
                  "NUM"= rep(rnorm(36,10,1)),
                  "TEST" = rep(NA,36))

DF2 <- data.frame("A" = rep("A",6),
                  "B" = rep(c("C","D"),6),
                  "VAL" = rep(c(1,3),3))

* Примечание: каждая уникальная комбинация переменных A а также B в DF2 должен иметь уникальный VAL,

Для каждой строки я хотел бы заменить NA в TEST с соответствующим значением VAL в DF1 если значения в столбцах A а также A совпадение и значения в столбцах B а также B соответствовать для этого ряда. В противном случае я бы ушел TEST как NA, Как бы я сделал это, не просматривая каждую комбинацию, используя матч?

В идеале ответ должен масштабироваться до двух фреймов данных с множеством столбцов для сопоставления.

2 ответа

Решение

Как Акрун упомянул в комментариях, ваша справочная таблица (DF2) должна быть сведена только к ее уникальным комбинациям A/B. Для вашего текущего фрейма данных это не проблема, но вам потребуются дополнительные правила, если существует несколько возможных значений для одной и той же комбинации. Оттуда решение легко:

DF2.u <- unique(DF2)
DF3 <- merge(DF1, DF2.u, all = T)

Обратите внимание, что это создаст новый фрейм данных с пустым столбцом TEST (все значения NA) и столбец VAL, назначенный из DF2. Чтобы сделать именно то, что вы хотели (замените TEST на VAL, где это возможно), вот немного неуклюжий код:

DF1$TEST <- merge(DF1, DF2.u, all = T)$VAL

РЕДАКТИРОВАТЬ: в ответ на ваш вопрос, вы можете свести DF2 при необходимости довольно просто:

DF2$C <- c(1:12) #now unique() won't work
DF2.u <- unique(DF2[1:3])

 A B VAL
1 A C   1
2 A D   3
# this is your DF1    
DF1 <- data.frame("A" = rep(c("A","B"), 18),
                      "B" = rep(c("C","D","E"), 12),
                      "NUM"= rep(rnorm(36,10,1)),
                      "TEST" = rep(NA,36))

#this is a DF2 i created, with unique A, B, VAL
DF2 <- data.frame("A" = rep(c("A","B"),3),
                  "B" = rep(c("C","D","E"),2),
                  "VAL" = rep(1:6))

# and this is the answer of what i assume you want      
tmp <- merge(DF1,DF2, by=c("A","B"), all.x=TRUE, all.y=FALSE)
DF1[4] <- tmp[5]
Другие вопросы по тегам