根据时间序列中的前一行计数填充计数/总和

时间:2017-12-12 21:32:30

标签: r dplyr time-series tidyr spread

我已经为每个组(在第2组中)执行了一段时间内的事件计数(在第1组中)。我希望将Group 1事件分散到单独的列中,并使用Group 2和timestamp作为行。每个单元格将包含一段时间内的事件计数(当前日期到前4天)。

参见下面的例子,对于第2组(I& II)中的每一组,我计算了第1组中的事件A和L在4天内发生。

dates = as.Date(c("2011-10-09",
   "2011-10-15",
   "2011-10-16", 
   "2011-10-18", 
   "2011-10-21", 
   "2011-10-22", 
   "2011-10-24")) 
group1=c("A",
    "A",
    "A", 
    "A", 
    "L", 
    "L", 
    "A")
group2=c("I",
    "I",
    "I", 
    "I", 
    "I", 
    "I", 
    "II")

df1 <- data.frame(dates, group1, group2) 

使用dplyr管道我设法生成下表(另见Count event types over time series by multiple conditions

df1 %>%
  group_by(group1, group2) %>%
  mutate(count = sapply(dates
                    , function(x){
                      sum(dates <= x & dates > (x-4))
                      }))


   dates group1 group2 count
  <date> <fctr> <fctr> <int>
1 2011-10-09      A      I     1
2 2011-10-15      A      I     1
3 2011-10-16      A      I     2
4 2011-10-18      A      I     3
5 2011-10-21      L      I     1
6 2011-10-22      L      I     2
7 2011-10-24      A     II     1

最终,我希望获得一个类似于此的表格,其中包含事件A&amp; L根据I&amp;中的日期(时间段=当前日期 - 4天)计数更新。 II(第2组)。

         dates  group1 group2  count (A)   count (L)
     1 2011-10-09      A      I        1         0
     2 2011-10-15      A      I        1         0
     3 2011-10-16      A      I        2         0
     4 2011-10-18      A      I        3         0
     5 2011-10-21      L      I        0         1
     6 2011-10-22      L      I        0         2
     7 2011-10-24      A      II       1         0

在较大的数据集中,并非组1中的所有事件都出现在每个组2中。 如何更新这些空单元格,以便它可以1)从前一行继承计数,或者2)根据更新的时间戳/时间段更新计数?

谢谢!

1 个答案:

答案 0 :(得分:0)

虽然目前还不清楚你想要什么(见问题评论),但这里有两种可能的方法。

如果您要做的就是将count列分散出去(由于某种原因)并填充0(前4天内是否有事件)仍由{{{ 1}}细分(即使您只是按group2标记)并保留事件详细信息(如您问题中的示例),您只需创建一个包含所需标签的列,然后使用{{ 1}}创建新列。此

group1

返回:

spread

哪个与您在问题中显示的输出相匹配。但是,如果您想要的是任何一天的事件,并且每个group1的事件发生了多少事件,您将需要更进一步。为此,您需要生成一个包含所需日期的新数据框 - 每个组都有一行。使用df1 %>% group_by(group1, group2) %>% mutate(count = sapply(dates , function(x){ sum(dates <= x & dates > (x-4)) })) %>% ungroup() %>% mutate(toSpread = paste0("Count (", group1, ")")) %>% spread(toSpread, count, fill = 0) 中的 dates group1 group2 `Count (A)` `Count (L)` * <date> <fctr> <fctr> <dbl> <dbl> 1 2011-10-09 A I 1 0 2 2011-10-15 A I 1 0 3 2011-10-16 A I 2 0 4 2011-10-18 A I 3 0 5 2011-10-21 L I 0 1 6 2011-10-22 L I 0 2 7 2011-10-24 A II 1 0 可以很容易地获得此信息。然后,您可以检查该组中前四天发生的事件中的每一个。

complete

返回:

tidyr

请注意,如果您想要包含没有活动的日期,可以将要检查的日期传递到df1 %>% select(dates, group1) %>% complete(dates, group1) %>% mutate(count = sapply(1:n() , function(idx){ sum(df1$dates <= dates[idx] & df1$dates > (dates[idx]-4) & df1$group1 == group1[idx]) })) %>% mutate(group1 = paste0("Count (", group1, ")")) %>% spread(group1, count, fill = 0) 。例如:

# A tibble: 7 x 3
       dates `Count (A)` `Count (L)`
*     <date>       <dbl>       <dbl>
1 2011-10-09           1           0
2 2011-10-15           1           0
3 2011-10-16           2           0
4 2011-10-18           3           0
5 2011-10-21           1           1
6 2011-10-22           0           2
7 2011-10-24           1           2

返回:

complete

根据评论,我想我终于明白了目标。首先,我将从上面开始创建一个“长”数据框,其中包含每个日期的每个group1 / group2对的计数:

df1 %>%
  select(dates, group1) %>%
  complete(dates = full_seq(dates, 1), group1) %>%
  mutate(count = sapply(1:n()
                        , function(idx){
                          sum(df1$dates <= dates[idx] &
                                df1$dates > (dates[idx]-4) &
                                df1$group1 == group1[idx])
                        })) %>%
  mutate(group1 = paste0("Count (", group1, ")")) %>%
  spread(group1, count, fill = 0)

最重要的是:

        dates `Count (A)` `Count (L)`
 *     <date>       <dbl>       <dbl>
 1 2011-10-09           1           0
 2 2011-10-10           1           0
 3 2011-10-11           1           0
 4 2011-10-12           1           0
 5 2011-10-13           0           0
 6 2011-10-14           0           0
 7 2011-10-15           1           0
 8 2011-10-16           2           0
 9 2011-10-17           2           0
10 2011-10-18           3           0
11 2011-10-19           2           0
12 2011-10-20           1           0
13 2011-10-21           1           1
14 2011-10-22           0           2
15 2011-10-23           0           2
16 2011-10-24           1           2

从那里,如果你真的需要转换为宽格式,你可以为每个group2(或者group1,如果你切换列名称)添加一行:

fullDateCounts <-
  df1 %>%
  select(dates, group1, group2) %>%
  complete(dates = full_seq(dates, 1), group1, group2) %>%
  mutate(count = sapply(1:n()
                        , function(idx){
                          sum(df1$dates <= dates[idx] &
                                df1$dates > (dates[idx]-4) &
                                df1$group1 == group1[idx] &
                                df1$group2 == group2[idx]
                              )
                        }))

返回:

        dates group1 group2 count
       <date> <fctr> <fctr> <int>
 1 2011-10-09      A      I     1
 2 2011-10-09      A     II     0
 3 2011-10-09      L      I     0
 4 2011-10-09      L     II     0
 5 2011-10-10      A      I     1
 6 2011-10-10      A     II     0
 7 2011-10-10      L      I     0
 8 2011-10-10      L     II     0
 9 2011-10-11      A      I     1
10 2011-10-11      A     II     0
# ... with 54 more rows

或者,您可以为每个group1 / group2对生成一列:

fullDateCounts %>%
  mutate(group1 = paste0("Count (", group1, ")")) %>%
  spread(group1, count, fill = 0)

返回

        dates group2 `Count (A)` `Count (L)`
 *     <date> <fctr>       <dbl>       <dbl>
 1 2011-10-09      I           1           0
 2 2011-10-09     II           0           0
 3 2011-10-10      I           1           0
 4 2011-10-10     II           0           0
 5 2011-10-11      I           1           0
 6 2011-10-11     II           0           0
 7 2011-10-12      I           1           0
 8 2011-10-12     II           0           0
 9 2011-10-13      I           0           0
10 2011-10-13     II           0           0
# ... with 22 more rows