根据时间序列中的前一行计数填充 count/sum
Fill count/sum based on previous row count over time series
我对每个组(第 2 组)在一段时间内对事件(第 1 组)进行了计数。我希望将第 1 组事件分散到单独的列中,并使用第 2 组和时间戳作为行。每个单元格将包含一段时间内的事件计数(当前日期到前 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 管道,我设法生成了以下 table(另请参阅 )
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
最终,我想获得与此类似的 table,在 I 和 II(第 2 组)中,事件 A 和 L 计数根据日期(时间段 = 当前日期 - 4 天)更新.
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) 根据更新的时间戳/时间段更新计数?
谢谢!
虽然您仍然不太清楚您想要什么(请参阅问题评论),但这里有两种可能的方法。
如果您只想将 count
列展开(出于某种原因)并用 0 填充(无论前 4 天是否发生事件)并且仍按group2
细分(即使你只用 group1
标记)并保留事件详细信息(如你问题中的示例),你可以只创建一个包含你想要的标签的列,然后使用spread
创建新列。这个
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)
returns这个:
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
这与您在问题中显示的输出相匹配。但是,如果您想要在任何一天计算每个 group1 的事件中发生了多少事件,则您需要退后一步。为此,您需要生成一个包含所需日期的新数据框——每组一行。使用 tidyr
中的 complete
很容易获得。然后,您可以检查每个组在前四天发生的事件。
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)
returns:
# 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
中来实现。例如:
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)
returns:
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
根据评论,我想我终于理解了目标。首先,如上所述,我首先创建一个 "long" 数据框,其中包含每个日期的每个 group1/group2 对的计数:
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
从那里开始,如果您真的需要转换为宽格式,您可以为每个 group2(或 group1,如果您切换列名称)一行:
fullDateCounts %>%
mutate(group1 = paste0("Count (", group1, ")")) %>%
spread(group1, count, fill = 0)
returns:
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
或者,您可以为每个 group1/group2 对生成一个列:
fullDateCounts %>%
mutate(toSpread = paste0("Count (", group1, "-", group2, ")")) %>%
select(-group1, -group2) %>%
spread(toSpread, count, fill = 0)
returns
dates `Count (A-I)` `Count (A-II)` `Count (L-I)` `Count (L-II)`
* <date> <dbl> <dbl> <dbl> <dbl>
1 2011-10-09 1 0 0 0
2 2011-10-10 1 0 0 0
3 2011-10-11 1 0 0 0
4 2011-10-12 1 0 0 0
5 2011-10-13 0 0 0 0
6 2011-10-14 0 0 0 0
7 2011-10-15 1 0 0 0
8 2011-10-16 2 0 0 0
9 2011-10-17 2 0 0 0
10 2011-10-18 3 0 0 0
11 2011-10-19 2 0 0 0
12 2011-10-20 1 0 0 0
13 2011-10-21 1 0 1 0
14 2011-10-22 0 0 2 0
15 2011-10-23 0 0 2 0
16 2011-10-24 0 1 2 0
我对每个组(第 2 组)在一段时间内对事件(第 1 组)进行了计数。我希望将第 1 组事件分散到单独的列中,并使用第 2 组和时间戳作为行。每个单元格将包含一段时间内的事件计数(当前日期到前 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 管道,我设法生成了以下 table(另请参阅
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
最终,我想获得与此类似的 table,在 I 和 II(第 2 组)中,事件 A 和 L 计数根据日期(时间段 = 当前日期 - 4 天)更新.
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) 根据更新的时间戳/时间段更新计数?
谢谢!
虽然您仍然不太清楚您想要什么(请参阅问题评论),但这里有两种可能的方法。
如果您只想将 count
列展开(出于某种原因)并用 0 填充(无论前 4 天是否发生事件)并且仍按group2
细分(即使你只用 group1
标记)并保留事件详细信息(如你问题中的示例),你可以只创建一个包含你想要的标签的列,然后使用spread
创建新列。这个
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)
returns这个:
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
这与您在问题中显示的输出相匹配。但是,如果您想要在任何一天计算每个 group1 的事件中发生了多少事件,则您需要退后一步。为此,您需要生成一个包含所需日期的新数据框——每组一行。使用 tidyr
中的 complete
很容易获得。然后,您可以检查每个组在前四天发生的事件。
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)
returns:
# 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
中来实现。例如:
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)
returns:
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
根据评论,我想我终于理解了目标。首先,如上所述,我首先创建一个 "long" 数据框,其中包含每个日期的每个 group1/group2 对的计数:
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
从那里开始,如果您真的需要转换为宽格式,您可以为每个 group2(或 group1,如果您切换列名称)一行:
fullDateCounts %>%
mutate(group1 = paste0("Count (", group1, ")")) %>%
spread(group1, count, fill = 0)
returns:
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
或者,您可以为每个 group1/group2 对生成一个列:
fullDateCounts %>%
mutate(toSpread = paste0("Count (", group1, "-", group2, ")")) %>%
select(-group1, -group2) %>%
spread(toSpread, count, fill = 0)
returns
dates `Count (A-I)` `Count (A-II)` `Count (L-I)` `Count (L-II)`
* <date> <dbl> <dbl> <dbl> <dbl>
1 2011-10-09 1 0 0 0
2 2011-10-10 1 0 0 0
3 2011-10-11 1 0 0 0
4 2011-10-12 1 0 0 0
5 2011-10-13 0 0 0 0
6 2011-10-14 0 0 0 0
7 2011-10-15 1 0 0 0
8 2011-10-16 2 0 0 0
9 2011-10-17 2 0 0 0
10 2011-10-18 3 0 0 0
11 2011-10-19 2 0 0 0
12 2011-10-20 1 0 0 0
13 2011-10-21 1 0 1 0
14 2011-10-22 0 0 2 0
15 2011-10-23 0 0 2 0
16 2011-10-24 0 1 2 0