【问题标题】:time between different events that may happen at the same time可能同时发生的不同事件之间的时间
【发布时间】:2021-02-04 10:03:53
【问题描述】:

我想获取多个重复发生的事件类型之间的时间,这些事件类型也可能同时发生,看起来像这样

      group   time type1 type2 type3
 [1,]     1  18262    0    0    0
 [2,]     2    520    0    1    1
 [3,]     2   6324    1    1    1
 [4,]     3 -27998    0    1    0
 [5,]     3 -27393    0    1    0
 [6,]     3   5490    0    0    0
 [7,]     3   6366    0    1    1
 [8,]     3  12548    0    1    1
 [9,]     4  13216    0    0    0
[10,]     5  18262    0    0    0
[11,]     6    976    1    0    1
[12,]     6  15952    1    0    1
[13,]     7   3580    0    0    0
[14,]     8   4207    1    0    1
[15,]     9   -815    1    0    1
[16,]     9   2316    1    0    1
[17,]     9   3245    1    1    1
[18,]     9   4062    0    1    0
[19,]     9   5995    1    0    1

我想按组计算最后一个事件类型 2 和事件类型 3 之间的时间。否则,意味着当该组中在类型 3 之前没有先前的事件类型 2 时,该变量应为 NA。

      group   time type1 type2 type3  t_type2_to_type3
 [1,]     1  18262    0    0    0     NA
 [2,]     2    520    0    1    1     NA
 [3,]     2   6324    1    1    1     5804
 [4,]     3 -27998    0    1    0     NA
 [5,]     3 -27393    0    1    0     0
 [6,]     3   5490    0    0    0     NA
 [7,]     3   6366    0    1    1     33759
 [8,]     3  12548    0    1    1     6182
 [9,]     4  13216    0    0    0     NA
[10,]     5  18262    0    0    0     NA
[11,]     6    976    1    0    1     NA
[12,]     6  15952    1    0    1     NA
[13,]     7   3580    0    0    0     NA
[14,]     8   4207    1    0    1     NA
[15,]     9   -815    1    0    1     NA
[16,]     9   2316    1    0    1     NA
[17,]     9   3245    1    1    1     NA
[18,]     9   4062    0    1    0     NA
[19,]     9   5995    1    0    1     1933

只为一个事件这样做似乎很简单。但是对于可能同时发生的多个重复事件似乎要困难得多

输入数据:

dat <- cbind(
  c(1,2,2,3,3,3,3,3,4,5,6,6,7,8,9,9,9,9,9),
  c(18262, 520, 6324, -27998, -27393, 5490, 6366, 12548, 13216, 18262, 976, 15952, 3580, 4207, -815, 2316, 3245, 4062, 5995),
  c(0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1),
  c(0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0),
  c(0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1)
) 

colnames(dat) <- c("group", "time", "type1", "type2", "type3")

编辑:

很高兴知道如何使用 dplyr 做到这一点

【问题讨论】:

  • 您想要的输出的第 7 行似乎有错字...我认为它应该是33759,因为6366 - -27393 = 33759 而不是34359.. 对吗?您可能减去了27.993 而不是27.393
  • 谢谢@Wimpel,我更正了。

标签: r events time


【解决方案1】:

这是一个高度灵活的data.table 解决方案。 它允许您选择两个变量(在本例中为 type2 和 type3),但您可以轻松更改变量名称并添加新列(例如任何 type3 的先前 type1 等...)

library( data.table )
DT <- as.data.table(dat)
#set variables, 
#  run again from here to add new columns like t_type3_to_type1 
#  by setting var1 <- "type3"  and var2 <- "type1"
var1 <- "type3"
var2 <- "type2"
#new clumn-name will be set autmatically based on vars
colname <- paste("t", var1, "to",  var2, sep="_")
#melt to long
DT.melt <- melt(DT, id.vars = c("group", "time"), measure.vars = patterns("^type"))
#only keep 1's
DT.melt <- DT.melt[ value == 1, ]
#set keys
setkey( DT.melt, group, time )
#get time of previous type2 for all rows with type2
temp <- DT.melt[ variable == var1 & value == 1, ][ DT.melt, 
                              (colname) := {
                                #create on-the-fly subset
                                val = DT.melt[ group == i.group & value == 1 & variable == var2 & time < i.time, ]
                                list( min( i.time - val$time ) )
                             }, by = .EACHI ][]

temp[ is.infinite( get(colname) ), (colname) := NA ][]
#    group  time variable value t_type3_to_type2
# 1:     2   520    type3     1               NA
# 2:     2  6324    type3     1             5804
# 3:     3  6366    type3     1            33759
# 4:     3 12548    type3     1             6182
# 5:     6   976    type3     1               NA
# 6:     6 15952    type3     1               NA
# 7:     8  4207    type3     1               NA
# 8:     9  -815    type3     1               NA
# 9:     9  2316    type3     1               NA
#10:     9  3245    type3     1               NA
#11:     9  5995    type3     1             1933

# join back to original
# use eval+parse to keep the colname variable
expr = paste0("DT[ temp, (colname) := i.", colname, ", on = .(group, time)]")
eval(parse(text=expr))

DT

#   group   time type1 type2 type3 t_type3_to_type2
# 1:    1  18262     0     0     0               NA
# 2:    2    520     0     1     1               NA
# 3:    2   6324     1     1     1             5804
# 4:    3 -27998     0     1     0               NA
# 5:    3 -27393     0     1     0               NA
# 6:    3   5490     0     0     0               NA
# 7:    3   6366     0     1     1            33759
# 8:    3  12548     0     1     1             6182
# 9:    4  13216     0     0     0               NA
# 10:   5  18262     0     0     0               NA
# 11:   6    976     1     0     1               NA
# 12:   6  15952     1     0     1               NA
# 13:   7   3580     0     0     0               NA
# 14:   8   4207     1     0     1               NA
# 15:   9   -815     1     0     1               NA
# 16:   9   2316     1     0     1               NA
# 17:   9   3245     1     1     1               NA
# 18:   9   4062     0     1     0               NA
# 19:   9   5995     1     0     1             1933

【讨论】:

  • 您会因为了解 OP 想要什么而获得 +1。我还是不明白!
【解决方案2】:

现在不在控制台上,所以在 rdrr.io/sn-ps 上运行代码 - 抱歉不能让它变得非常好。我会寻找 type1 == 1 的最大索引和 type2 == 1 的最小索引,然后取差值。

library(tidyverse)
dat <- as.data.frame(cbind(
  c(1,2,2,3,3,3,3,3,4,5,6,6,7,8,9,9,9,9,9),
  c(18262, 520, 6324, -27998, -27393, 5490, 6366, 12548, 13216, 18262, 976, 15952, 3580, 4207, -815, 2316, 3245, 4062, 5995),
  c(0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1),
  c(0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0),
  c(0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1)
) )

colnames(dat) <- c("group", "time", "type1", "type2", "type3")
dat %>%
arrange(group, time) %>%
group_by(group) %>% 
mutate(maxtime1 = max(which(as.logical(type1))),
mintime2 = min(which(as.logical(type2))),
diff1_2 = time[mintime2]-time[maxtime1])

# A tibble: 19 x 8
# Groups:   group [9]
   group   time type1 type2 type3 maxtime1 mintime2 diff1_2
   <dbl>  <dbl> <dbl> <dbl> <dbl>    <dbl>    <dbl>   <dbl>
 1     1  18262     0     0     0     -Inf      Inf      NA
 2     2    520     0     1     1        2        1   -5804
 3     2   6324     1     1     1        2        1   -5804
 4     3 -27998     0     1     0     -Inf        1      NA
 5     3 -27393     0     1     0     -Inf        1      NA
 6     3   5490     0     0     0     -Inf        1      NA
 7     3   6366     0     1     1     -Inf        1      NA
 8     3  12548     0     1     1     -Inf        1      NA
 9     4  13216     0     0     0     -Inf      Inf      NA
10     5  18262     0     0     0     -Inf      Inf      NA
11     6    976     1     0     1        2      Inf      NA
12     6  15952     1     0     1        2      Inf      NA
13     7   3580     0     0     0     -Inf      Inf      NA
14     8   4207     1     0     1        1      Inf      NA
15     9   -815     1     0     1        5        3   -2750
16     9   2316     1     0     1        5        3   -2750
17     9   3245     1     1     1        5        3   -2750
18     9   4062     0     1     0        5        3   -2750
19     9   5995     1     0     1        5        3   -2750
There were 22 warnings (use warnings() to see them)

这不是超级优雅,但它应该可以满足您的需求 - 抱歉警告,我认为您可以忽略它。我需要摆弄一下,但为此我需要一个控制台:) 负数表明我可能没有完全理解你在寻找什么。

【讨论】:

  • 非常感谢您的尝试,但结果与我想要的输出不同。然而,@Wimpel 的回应似乎产生了正确的结果。如果你能拿到控制台,我仍然会对 dplyr 解决方案感兴趣。
  • @SFront 检查您的问题 - 您要求我计算出类型 1 和类型 2 之间的区别,但在您的示例和 Wimpel 的示例中,使用了类型 2/3。您是否尝试过简单地更改我的代码中的那些???
  • 是的,你是对的,很抱歉对这个问题如此草率:/我将按照所需的输出适应 type2 到 type3。但我认为它并没有太大变化
猜你喜欢
  • 1970-01-01
  • 2020-10-29
  • 1970-01-01
  • 1970-01-01
  • 2021-03-06
  • 1970-01-01
  • 2013-01-08
  • 2023-03-13
  • 1970-01-01
相关资源
最近更新 更多