R:基于多个条件的两个数据帧的子集

Posted

技术标签:

【中文标题】R:基于多个条件的两个数据帧的子集【英文标题】:R: Subset from two data frames based on multiple conditions 【发布时间】:2019-10-22 04:04:50 【问题描述】:

我有两个数据框(df1 和 df2),我想要一个新的数据框 (df3),其中包含 df1 的“日期”和“time_of_day”与 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 

【问题讨论】:

试试inner_join(df1, df2)anti_join(df1, df2) 【参考方案1】:

我们可以通过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

数据

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"))

【讨论】:

非常感谢,我认为这会有所帮助,我现在唯一的问题是,我的真实 df2 中的列比 df1 中的多,所以我没有达到我需要。你知道我该如何解决吗? @chiarasahara 只是对 'df2' 的列进行子集化,即仅使用列加入 inner_join(df1, df2[c("date", "time_of_day")]) 我的真实数据似乎无法获得相同的输出。结构是一样的。但在我的 df3 中,现在所有日期都是双倍或三倍版本。你知道为什么吗? @chiarasahara 在这种情况下,您可能需要决定匹配哪一行。您可以使用distinct 获取保留第一行的不同行并删除重复项,即。 distinct(df2[c("date", "time_of_day")]) 然后加入。但是,这个决定取决于你的问题,以及你想要实现的逻辑 哇,现在我得到了我的结果,非常感谢你的耐心:) 你让我开心!【参考方案2】:

更改您的基本 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 &amp; df1$time_of_day %in% df2$time_of_day 的计算结果为 TRUE TRUE TRUE TRUE。所以它保留了所有行。也就是说:df1 中的所有日期都在df2 中,df1 中的所有时间都在df2 中。

编辑:

或者,在 dplyr 中,您可以使用 intersectsetdiff 处理数据帧并删除重复项:

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

【讨论】:

以上是关于R:基于多个条件的两个数据帧的子集的主要内容,如果未能解决你的问题,请参考以下文章

如何使用“OR”组合多个条件以对数据框进行子集化?

在R中将具有不同长度和两个条件的不同数据帧的列相乘

使用多索引上的条件选择数据帧的子集

Pandas:根据条件为多索引数据帧的子集设置值的正确方法

基于多个条件的子集数据框[重复]

R中数据帧的条件求和