过滤行"分组键"随着时间的推移至少改变一次

时间:2015-08-04 09:11:41

标签: r data.table dplyr

我有一个数据框,每日观察个人。在示例中,我将数据集减少为3个变量,标识个人的日期和两个ID。一个人通过两个ID来识别,但是有一天,其中一个ID可能会丢失(并在另一天重新出现),但这仍然是同一个人。

例如,这是对同一个人的观察:

   Day id1  id2
1 Day1   1    x
2 Day2  NA    x
3 Day3   1 <NA>

此外,每天都可以找到相同的人,或者他们可以从一天到另一天出现/消失。 (例如,id1 = 4&amp; id2 = d bellow)

我想保留情侣id1,id2在几天内至少更改一次的行。

我不知道这是否足够清楚所以这里是虚拟数据:

datas <- data.frame(id1 = c(1, 2, 3, 1, 2, 3, 4, NA, 2, 3, 4), 
                id2 = c(NA, "b", "c", "a", "b", "c", "d", "a", NA, "c", "d"),
                date = rep(seq(Sys.Date() - 2, Sys.Date(), by = "day"), each = 4)[-4])

   id1  id2       date
1    1 <NA> 2015-08-02
2    2    b 2015-08-02
3    3    c 2015-08-02
4    1    a 2015-08-03
5    2    b 2015-08-03
6    3    c 2015-08-03
7    4    d 2015-08-03
8   NA    a 2015-08-04
9    2 <NA> 2015-08-04
10   3    c 2015-08-04
11   4    d 2015-08-04

我期待的输出:

    id1  id2       date
 1    1 <NA> 2015-08-02
 2    2    b 2015-08-02
 3    1    a 2015-08-03
 4    2    b 2015-08-03
 5   NA    a 2015-08-04
 6    2 <NA> 2015-08-04

我以为我对这段代码有所了解:

datas.dt <- data.table(datas, key = c("id1", "id2"))

datas.dt[datas.dt[ , .N, by = c("id1", "id2")][N != length(unique(datas.dt$date))]]

   id1 id2       date N
1:  NA   a 2015-08-04 1
2:   1  NA 2015-08-02 1
3:   1   a 2015-08-03 1
4:   2  NA 2015-08-04 1
5:   2   b 2015-08-02 2
6:   2   b 2015-08-03 2
7:   4   d 2015-08-03 2
8:   4   d 2015-08-04 2

#Or with dplyr

datas.tbl <- tbl_df(datas)

datas.tbl %>% 
  count(id1, id2) %>% 
  filter(n != length(unique(datas.tbl$date))) %>% 
  inner_join(datas.tbl, by = c("id1", "id2"))

但如果个人对数据集中的所有日期都没有观察结果(例如,情况id2 = d),则会失败。 而目前我不知道如何实现这一目标。任何帮助将受到高度赞赏。谢谢!

2 个答案:

答案 0 :(得分:4)

这是你想要的吗?

declare @catch numeric (20)
select @catch = Exec ('select COUNT(*) from ' + @full_name) ;
update dbo.validate set cnt = @catch
where tb_schema = @tb_schema and tb_name =@tb_name  ;

输出:

filter_id1 <- setDT(datas)[ , length(unique(id2)), by = id1][ V1 > 1, id1]
filter_id2 <- datas[ , length(unique(id1)), by = id2][ V1 > 1, id2]

datas[ id1 %in% filter_id1 | id2 %in% filter_id2]

答案 1 :(得分:4)

首先,通过创建一个新的来清理ID:

idmap = unique( na.omit(datas)[,.(id1,id2)] )[,id0 := .I]

datas[idmap, id0 := i.id0, on="id1"]
datas[idmap, id0 := i.id0, on="id2"]

然后选择组:

datas[
  sort( datas[, .I[ uniqueN(.SD) > 1 ], by=id0, .SDcols=c("id1","id2")]$V1 )
]

这种方法是borrowed from @eddi

行号对象.I在这里是关键。默认情况下,它生成的列名为V1。获得这些行号后,我们可以通常的方式datasdatas[row_numbers]进行分组。