选择由ID和其他数据帧中给出的其他条件限制的多个行

时间:2017-04-25 09:12:55

标签: r

我们说我有一个带月销售票据的数据框,有一个ID客户端,月份和金额。

head(tickets)
  id_client      month sales
1   ID87160 2016-01-01 16875
2   ID18694 2016-01-01   448
3   ID20624 2016-01-01 16311
4  ID171683 2016-01-01   314
5  ID214926 2016-01-01  8889
6   ID82071 2016-01-01  7479

我有另一个data.frame,我有客户取消订阅的时刻。

head(stop_being_client)
  id_client       date
1  ID235005 2016-03-01
2   ID50615 2016-04-01
3   ID72078 2016-03-01
4  ID129556 2016-01-01
5  ID204060 2016-04-01
6   ID57769 2016-01-01

现在我需要检查门票表中是否存在未订阅的客户注册,即门票中的月份大于stop_being_client中的日期。

在PostgreSQL中很简单:

SELECT
    *
FROM
    tickets
JOIN
    stop_being_client
ON
    tickets.id_client = stop_being_client.id_client
WHERE
    tickets.month > stop_being_client.date;

但我不知道如何在R中做到这一点。我尝试了这个

tickets[which(
    tickets$id_client %in% stop_being_client$id_client &
    tickets$month > stop_being_client$date
    ),]

但是我很确定结果不是我想要的,因为在比较日期时我需要将两个表中的id_client联系起来。

编辑:我举了一个例子:

这是门票data.frame:

id_client      month sales
      ID2 2016-01-01 12698
      ID1 2016-01-01  8626
      ID2 2016-02-01 18309
      ID1 2016-02-01 15653
      ID3 2016-02-01  9642
      ID3 2016-03-01 18376
      ID1 2016-03-01 13440
      ID2 2016-03-01  2322
      ID1 2016-04-01 19010
      ID3 2016-04-01  7129
      ID2 2016-04-01 14694
      ID2 2016-05-01  4726
      ID1 2016-05-01   706
      ID3 2016-05-01 16995
      ID1 2016-06-01 18743
      ID3 2016-06-01 16725
      ID2 2016-07-01  2632

这是表stop_being_client:

id_client       date
      ID1 2016-03-01
      ID2 2016-04-01

所以我想检测故障单中的那些行,在那种情况下不应该存在:

id_client      month sales
      ID1 2016-04-01 19010
      ID2 2016-05-01  4726
      ID1 2016-05-01   706
      ID1 2016-06-01 18743
      ID2 2016-07-01  2632

2 个答案:

答案 0 :(得分:1)

这是基于R的想法,

l4 <- split(df, df$id_client)
do.call(rbind, lapply(Map(cbind, l4, temp = ind1), function(i){
                                     i <- i[i$month > i$temp[!is.na(i$temp)],]; 
                                     i$temp <- NULL; i
                                     }))


#       id_client      month sales
#ID1.9        ID1 2016-04-01 19010
#ID1.13       ID1 2016-05-01   706
#ID1.15       ID1 2016-06-01 18743
#ID2.12       ID2 2016-05-01  4726
#ID2.17       ID2 2016-07-01  2632

答案 1 :(得分:0)

使用data.table

library(data.table)
setDT(tickets)
setDT(stop_being_client)

stop_being_client[tickets, on = .(date < month, id_client==id_client),nomatch=0,.(id_client,month,date,sales)]

id_client      month       date sales
1:       ID1 2016-04-01 2016-04-01 19010
2:       ID2 2016-05-01 2016-05-01  4726
3:       ID1 2016-05-01 2016-05-01   706
4:       ID1 2016-06-01 2016-06-01 18743
5:       ID2 2016-07-01 2016-07-01  2632