Сопоставление значений на основе нескольких условий из фреймов данных разного размера в R

#r #dataframe #match

#r #фрейм данных #совпадение

Вопрос:

У меня есть два фрейма данных разных размеров. Пример:

 t1 <- data.frame("id"=c(1,1,1,2,2,2,4,5,5,5,6,7,8),"condition"=c(3,3,1,5,5,5,10,10,5,5,2,3,1) )
t2 <- data.frame("ind"=c(1,2,4,5,6,7,8),"test_c"=c(3,5,10,10,2,3,1), "time"=c(32,55,21,34,55,22,19))
 

Я хотел бы сопоставить случаи, основанные на двух критериях:
t1$id==t2$ind t1$condition==t2$test_c и создайте дополнительный столбец в t1 на основе результата переменной t2$time при этих двух условиях.

Ожидаемый результат:

 t3 <- data.frame("id"=c(1,1,1,2,2,2,4,5,5,5,6,7,8),"condition"=c(3,3,1,5,5,5,10,10,5,5,2,3,1) , "time"=c (32,32,NA,55,55,55,21,34,NA,NA,55,22,19))
 

Я подозреваю, что мне следует использовать merge match функции or, но я не уверен, какой подход будет правильным.

Комментарии:

1. Почему в вашем ожидаемом результате id=1,condition=1 получается время 32? Это ничего не соответствует в исходных фреймах. К вашему сведению, merge(t1, t2, by.x=c("id","condition"), by.y=c("ind","test_c"), all.x=TRUE) это начало.

2. Прошу прощения за это, см. Отредактированный вывод. 32 означает значение t2$time для t1$id=t2£ind=1 и t1$condition=te2$test_c=3

Ответ №1:

Основание R

 > out <- merge(t1, t2, by.x=c("id","condition"), by.y=c("ind","test_c"), all.x=TRUE)
> out
   id condition time
1   1         1   NA
2   1         3   32
3   1         3   32
4   2         5   55
5   2         5   55
6   2         5   55
7   4        10   21
8   5         5   NA
9   5         5   NA
10  5        10   34
11  6         2   55
12  7         3   22
13  8         1   19
 

dplyr

 library(dplyr)
left_join(t1, t2, by = c("id" = "ind", "condition" = "test_c"))
 

Различия с вашим t3

Между ними есть некоторые различия. Для наглядности я покажу их рядом друг с другом, расположив так, чтобы нам было проще сравнивать.

 cbind(out[with(out,order(id,condition)),], t3[with(t3,order(id,condition)),])
#    id condition time id condition time
# 1   1         1   NA  1         1   NA
# 2   1         3   32  1         3   32
# 3   1         3   32  1         3   32
# 4   2         5   55  2         5   55
# 5   2         5   55  2         5   NA
# 6   2         5   55  2         5   NA
# 7   4        10   21  4        10   21
# 8   5         5   NA  5         5   NA
# 9   5         5   NA  5         5   NA
# 10  5        10   34  5        10   34
# 11  6         2   55  6         2   55
# 12  7         3   22  7         3   22
# 13  8         1   19  8         1   19
 

Единственные различия заключаются в id=2,condition=5 том, что всем им в merge присваивается одинаковое time=55 значение, а ваше t3 заполняет только первое из них. Я не думаю, что это логика «только для начала», поскольку есть и другие повторы id,condition , которые не вызывают такого же отклика. Я подозреваю, что это просто ошибка с образцами данных, или, возможно merge , есть постобработка, о которой вы нам еще не сказали 🙂

Комментарии:

1. Вы правы, это была просто ошибка с образцами данных, я отредактирую свой вопрос, большое спасибо 🙂

Ответ №2:

В случае, если вы хотите использовать match , вы можете использовать дополнительно interaction (или paste ) для использования нескольких столбцов.

 t1$time <- t2[match(interaction(t1), interaction(t2[-3])), 3]
t1
#   id condition time
#1   1         3   32
#2   1         3   32
#3   1         1   NA
#4   2         5   55
#5   2         5   55
#6   2         5   55
#7   4        10   21
#8   5        10   34
#9   5         5   NA
#10  5         5   NA
#11  6         2   55
#12  7         3   22
#13  8         1   19