按另一个Dataframe过滤数据帧

时间:2017-09-26 17:31:40

标签: r

据说这个问题已经得到解答。但是标记我的问题的用户未能测试解决方案,并且引用的问题对我的问题不起作用。

我发现了有关如何使用其他列表过滤数据框的问题,但我没有找到显示如何使用其他数据框过滤数据框的内容。

我有两个数据帧,第一个可以被认为是ID和日期的关键。

   id       date
1 id1 2016-06-23
2 id2 2016-06-25
3 id3 2016-06-23
4 id4 2016-06-25
5 id5 2016-06-27

structure(list(id = structure(1:5, .Label = c("id1", "id2", "id3", 
"id4", "id5"), class = "factor"), date = structure(c(16975, 16977, 
16975, 16977, 16979), class = "Date")), .Names = c("id", "date"
), row.names = c(NA, -5L), class = "data.frame")

然后我有第二个带有ID和日期的数据框,我想过滤第二个数据帧,只返回第一行中ID的日期之后的行。

这是第二个数据帧:

   id       date
1 id1 2016-06-20
2 id1 2016-06-23
3 id1 2016-06-24
4 id2 2016-06-23
5 id3 2016-06-27

structure(list(id = structure(c(1L, 1L, 1L, 2L, 3L), .Label = c("id1", 
"id2", "id3"), class = "factor"), date = structure(c(16972, 16975, 
16976, 16975, 16979), class = "Date")), .Names = c("id", "date"
), row.names = c(NA, -5L), class = "data.frame")

这就是结果的样子:

   id       date
1 id1 2016-06-24
2 id3 2016-06-27

4 个答案:

答案 0 :(得分:3)

data.table

中使用非等连接
library(data.table)

setDT(df1)
setDT(df2)

setnames(df1, 'date','date1') # disambiguate for conditional join

df1[df2, on=.(id, date1<date), nomatch=0]

返回:

  id      date1
1: id1 2016-06-24
2: id3 2016-06-27

在大型数据集上,我希望这种方法比使用dplyr和/或笛卡尔连接后跟过滤器的方法更快。

答案 1 :(得分:1)

感谢上帝有dplyr。以下代码连接具有唯一标识符的df1,并仅保留与条件filter匹配的这些行(date >= date.1)。

要小心,因为默认情况下,当两个data.frame中都有相同的列名时,dplyr将全部加入。然后我们必须指定by参数并将后缀添加到变量名称以使不同的列名称不同。

library(dplyr)
library(magrittr)

df2 %>%
 left_join(df1, by = "id", suffix=c("",".2") ) %>%
 filter( date > date.2) %>%
 select( -date.2 )

#  id       date
# 1 id1 2016-06-23
# 2 id1 2016-06-24
# 3 id3 2016-06-27

答案 2 :(得分:1)

使用data.table的解决方案:

library(data.table)
setDT(d1)
setDT(d2)
merge(d1, d2, "id")[date.y > date.x, .(id, date = date.y)]

    id       date
1: id1 2016-06-24
2: id3 2016-06-27

答案 3 :(得分:0)

所以你的第一个数据帧基本上就是一个索引。假设索引被称为df1,而你想要过滤的第二个数据帧是df2,我会用dplyr来做这个:

library(dplyr)

df.result <- left_join(df2, df1, by = "id") %>% 
   filter(date.x > date.y) %>% 
   select(-date.y) 

eta:结果就是这样:

   id     date.x
 1 id1 2016-06-24
 2 id3 2016-06-27
相关问题