R: Подмножество из двух фреймов данных на основе нескольких условий - PullRequest
2 голосов
/ 06 июня 2019

У меня есть два фрейма данных (df1 и df2), и я хочу новый фрейм данных (df3), содержащий все строки, в которых «date» И «time_of_day» для df1 совпадают с df2. И сохраните строки df1, которые также не совпадают, в новом фрейме данных (df4).

Я попытался использовать функцию фильтра dplyr, но кажется, что я не пишу это правильно, так как я получаю новый кадр данных той же длины, что и df1, но он должен показывать мне только совпадающие строки, основанные на обеих переменных даты и времени дня.

> df1
          date time_of_day     
1  2018-06-03     morning 
2  2018-06-06     afternoon 
4  2018-06-09     morning 
5  2018-06-10     afternoon 

> df2
          date time_of_day     
1  2018-06-03     morning 
2  2018-06-06     morning 
3  2018-06-08     morning 
4  2018-06-09     morning 
5  2018-06-10     afternoon
6  2018-06-11     afternoon

#creating a new data frame
df3 <- filter(df1, date %in% df2$date & time_of_day %in% df2$time_of_day)
#another try 
df3 <- df1[df1$date %in% df2$date & df1$time_of_day %in% df2$time_of_day,]

Вот что я хочу:

> df3
          date time_of_day     
1  2018-06-03     morning 
2  2018-06-09     morning 
3  2018-06-10     afternoon 

> df4
          date time_of_day     
1  2018-06-06     afternoon 

Ответы [ 2 ]

3 голосов
/ 06 июня 2019

Мы можем сделать это с inner_join

library(dplyr)
df3 <- inner_join(df1, df2)
df3
#       date time_of_day
#1 2018-06-03     morning
#2 2018-06-09     morning
#3 2018-06-10   afternoon

и anti_join

df4 <- anti_join(df1, df2)
df4
#       date time_of_day
#1 2018-06-06   afternoon

data

df1 <- structure(list(date = c("2018-06-03", "2018-06-06", "2018-06-09", 
"2018-06-10"), time_of_day = c("morning", "afternoon", "morning", 
"afternoon")), class = "data.frame", row.names = c("1", "2", 
"4", "5"))

df2 <- structure(list(date = c("2018-06-03", "2018-06-06", "2018-06-08", 
"2018-06-09", "2018-06-10", "2018-06-11"), time_of_day = c("morning", 
"morning", "morning", "morning", "afternoon", "afternoon")),
class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6"))
2 голосов
/ 06 июня 2019

Изменяя свой базовый код R, вы можете сделать это (ниже). И вы можете обернуть либо в unique(), если вы хотите удалить дубликаты строк.

df1[paste0(df1$date, df1$time_of_day) %in% paste0(df2$date, df2$time_of_day), ]
        date time_of_day
1 2018-06-03     morning
4 2018-06-09     morning
5 2018-06-10   afternoon

и

df1[!paste0(df1$date, df1$time_of_day) %in% paste0(df2$date, df2$time_of_day), ]
        date time_of_day
2 2018-06-06   afternoon

Ваши попытки раньше не сработали, потому что df1$date %in% df2$date & df1$time_of_day %in% df2$time_of_day оценивается как TRUE TRUE TRUE TRUE. Так что сохранились все ряды. То есть: все даты в df1 находятся в df2, а все времена дня в df1 - в df2.

EDIT:

В качестве альтернативы, в dplyr вы можете использовать intersect и setdiff, которые работают с фреймами данных и удаляют дубликаты:

dplyr::intersect(df1, df2)
        date time_of_day
1 2018-06-03     morning
2 2018-06-09     morning
3 2018-06-10   afternoon

dplyr::setdiff(df1, df2)
        date time_of_day
1 2018-06-06   afternoon
...