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 & df1$time_of_day %in% df2$time_of_day
的计算结果为 TRUE TRUE TRUE TRUE
。所以它保留了所有行。也就是说:df1
中的所有日期都在df2
中,df1
中的所有时间都在df2
中。
编辑:
或者,在 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
【讨论】:
以上是关于R:基于多个条件的两个数据帧的子集的主要内容,如果未能解决你的问题,请参考以下文章