在R中按组检查重叠开始和结束时间(当数据有NA时运行不正确)

时间:2016-08-26 21:13:04

标签: r data.table

这是this previous question的后续内容,但由于NA,我在那里提供的答案遇到了问题:

require(data.table)
ID <- c(rep(1,4), rep(3, 5), rep(4,4),rep(5,5))
Begin <- c(0,2.5,NA,3,7,8,7,25,25,10,15,0,0,1,NA,10,11,13)
End <- c(1.5,3.5,NA,6,12,8,11,29,35, 12,19,NA,28,5,20,30,20,25)
df <- data.table(ID, Begin, End)
df[, Begin_New := {
  high_so_far = shift(cummax(End), fill=Begin[1L])
  w = which(Begin < high_so_far)
  Begin[w] = high_so_far[w]
  Begin
}, by=ID]
    ID   Begin  End    Begin_New
  1:  1   0.0  1.5       0.0
  2:  1   2.5  3.5       2.5
  3:  1    NA   NA        NA
  4:  1   3.0  6.0       3.0* # <~~ it supposed 3.5
  5:  3   7.0 12.0       7.0
  6:  3   8.0  8.0      12.0
  7:  3   7.0 11.0      12.0
  8:  3  25.0 29.0      25.0
  9:  3  25.0 35.0      29.0
 10:  4  10.0 12.0      10.0
 11:  4  15.0 19.0      15.0
 12:  4   0.0   NA      19.0
 13:  4   0.0 28.0       0.0* # <~~ it's supposed 19.0
 14:  5   1.0  5.0       1.0
 15:  5    NA 20.0        NA
 16:  5  10.0 30.0      20.0
 17:  5  11.0 20.0      30.0
 18:  5  13.0 25.0      30.0

我尝试检查重叠,如果开始&lt;结束,Begin_New需要与每个ID的End previous相同,继续检查直到Begin&gt;结束,但是当我有End变量的NA时,代码不明白,继续检查值。我尝试了几个代码,但它没有工作

2 个答案:

答案 0 :(得分:5)

您可以在cummax之前添加另一个步骤:

df[, Begin_New := {
  End[is.na(End)] = 0 # <- new step here
  high_so_far = shift(cummax(End), fill=Begin[1L])
  w = which(Begin < high_so_far)
  Begin[w] = high_so_far[w]
  Begin
}, by=ID][]

我是如何得到这个的。要解决这类问题,我会一次为一个小组分步运行j

df[, if (.GRP == 1L){
  high_so_far = shift(cummax(End), fill=Begin[1L])
  print(high_so_far)
  # w = which(Begin < high_so_far)
  # Begin[w] = high_so_far[w]
  # Begin
}, by=ID][]

# 0.0 1.5 3.5  NA

因此,我可以看到问题发生的地方,并通过阅读?cummax来查看是否存在na.rm选项。在那里找不到一个,我可以考虑在这个之前或之后我可以采取的其他步骤来获得所需的结果。

如果我在此步骤中未找到问题,那么我可以逐步取消后续行的注释并添加更多print语句。或者我可以将.GRP==1更改为其他组。正如@jangorecki所提到的,有适当的调试方法,你也可以尝试:

  

您还可以将browser()置于j={...}内并以交互方式调查当前状态

答案 1 :(得分:1)

不确定我是否应该发布此消息但是@Arun发布了一个解决方案作为评论,但它只有在首先运行OP的代码时才有效。 Arun删除了他的评论并没有重新发布,所以我想我会把它作为答案发布,以便OP和其他人看到它。随意在其他地方给予信任。

.timeout()