微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

R / data.table:部分滚动连接

如何解决R / data.table:部分滚动连接

我具有以下数据结构:

> dt
   ID MiscInfo       Date Val
1:  A   info_a 2000-01-01   0
2:  A   info_a 2000-01-03   3
3:  B   info_b 2001-01-01   1
4:  B   info_b 2001-01-04   5
5:  B   info_b 2001-01-07  13

Date缺少一些ID明智的条目,其中Val == 0MiscInfo代表一组N > 50属性变量。我的最终目标是填写缺少的条目,以便获得以下结构。

> dt_pref
    ID MiscInfo       Date Val
 1:  A   info_a 2000-01-01   0
 2:  A   info_a 2000-01-02   0
 3:  A   info_a 2000-01-03   3
 4:  B   info_b 2001-01-01   1
 5:  B   info_b 2001-01-02   0
 6:  B   info_b 2001-01-03   0
 7:  B   info_b 2001-01-04   5
 8:  B   info_b 2001-01-05   0
 9:  B   info_b 2001-01-06   0
10:  B   info_b 2001-01-07  13 

similar requests来看,滚动连接是实现这一目标的一条不错的途径。我遇到的问题是无法选择要滚动的列,如下所述:

drange = dt[,.(Date = seq(min(Date),max(Date),1)),ID] %>% setkey(ID,Date)
dt[drange,roll = T]

    ID MiscInfo       Date Val
 1:  A   info_a 2000-01-01   0
 2:  A   info_a 2000-01-02   0
 3:  A   info_a 2000-01-03   3
 4:  B   info_b 2001-01-01   1
 5:  B   info_b 2001-01-02   1
 6:  B   info_b 2001-01-03   1
 7:  B   info_b 2001-01-04   5
 8:  B   info_b 2001-01-05   5
 9:  B   info_b 2001-01-06   5
10:  B   info_b 2001-01-07  13

在这种情况下,MiscInfo列会适当地滚动到我满意的程度,但是Val列当然也会滚动,而我希望将它们设置为等于0。我当然也可以在通过roll = 0传递另一个方向:

dt[drange,roll = 0]
    ID MiscInfo       Date Val
 1:  A   info_a 2000-01-01   0
 2:  A     <NA> 2000-01-02  NA
 3:  A   info_a 2000-01-03   3
 4:  B   info_b 2001-01-01   1
 5:  B     <NA> 2001-01-02  NA
 6:  B     <NA> 2001-01-03  NA
 7:  B   info_b 2001-01-04   5
 8:  B     <NA> 2001-01-05  NA
 9:  B     <NA> 2001-01-06  NA
10:  B   info_b 2001-01-07  13

在这种情况下,我当然可以应用类似dt[is.na(Val),Val := 0]方法,但是使用类似的路由来处理MiscInfo数组(非常大)的NA项在计算上并不高效,并且我怀疑存在与联接相关的方法来执行此操作。简而言之,我想将“已填充”条目的Val预置为0,并以有效的方式滚动剩余的列。有什么想法吗?

可复制品:

dt = data.table(
  ID = c('A','A','B','B'),MiscInfo = c(rep('info_a',2),rep('info_b',3)),Date = as.Date(c('2000-01-01','2000-01-03','2001-01-01','2001-01-04','2001-01-07')),Val = c(0,3,1,5,13)
) %>% setkey(ID,Date)

dt_pref = data.table(
  ID = c(rep('A',3),rep('B',7)),MiscInfo = c(rep("info_a",rep("info_b",Date = as.Date(c(10957,10958,10959,11323,11324,11325,11326,11327,11328,11329),origin = '1970-01-01'),13)
)

解决方法

即使在更复杂的情况下也可以使用:

merge(dt,dt[,.(Date = seq.Date(from = min(Date),to = max(Date),by = 1)),by = c("ID","MiscInfo") ],"Date"),all = TRUE)[,.(ID,Date,MiscInfo.y,Val = case_when(is.na(Val) ~ 0,TRUE ~ Val))]

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。