ulf*_*der 5 r time-series dplyr
我有一个面板数据集,我想为其创建一个计数器,该计数器随着面板中的每个步骤而增加,但只要发生某些情况就会重新启动.就我而言,我正在使用国家年度数据,并希望计算事件之间的年份.这是一个玩具数据集,其中包含我真实的主要特征:
df <- data.frame(country = rep(c("A","B"), each=5), year=rep(2000:2004, times=2), event=c(0,0,1,0,0,1,0,0,1,0), stringsAsFactors=FALSE)
Run Code Online (Sandbox Code Playgroud)
我想要做的是创建一个df$event在每个国家的一系列观察中都有关键的计数器.当我们开始观察每个国家时,时钟从1开始; 随着每年的过去,它增加1; 并且它会在1时重新启动df$event==1.所需的输出是这样的:
country year event clock
1 A 2000 0 1
2 A 2001 0 2
3 A 2002 1 1
4 A 2003 0 2
5 A 2004 0 3
6 B 2000 1 1
7 B 2001 0 2
8 B 2002 0 3
9 B 2003 1 1
10 B 2004 0 2
Run Code Online (Sandbox Code Playgroud)
我已经尝试使用getanID从splitstackshape和一些变化if和ifelse但到目前为止还没有得到期望的结果.
我已经dplyr在我需要这样做的脚本中使用了,所以我更喜欢使用它或基础R的解决方案,但我会感激任何有用的东西.我的数据集并不大,因此速度并不重要,但效率始终是一个优势.
tal*_*lat 15
有了dplyr这将是:
df %>%
group_by(country, idx = cumsum(event == 1L)) %>%
mutate(counter = row_number()) %>%
ungroup %>%
select(-idx)
#Source: local data frame [10 x 4]
#
# country year event counter
#1 A 2000 0 1
#2 A 2001 0 2
#3 A 2002 1 1
#4 A 2003 0 2
#5 A 2004 0 3
#6 B 2000 1 1
#7 B 2001 0 2
#8 B 2002 0 3
#9 B 2003 1 1
#10 B 2004 0 2
Run Code Online (Sandbox Code Playgroud)
或使用data.table:
library(data.table)
setDT(df)[, counter := seq_len(.N), by = list(country, cumsum(event == 1L))]
Run Code Online (Sandbox Code Playgroud)
编辑:group_by(country, idx = cumsum(event == 1L))用于按国家/地区分组和新的分组索引"idx".该event == 1L部分创建一个逻辑索引,告诉我们"事件"列是否为整数1(TRUE/ FALSE).然后,cumsum(...)总结从前2行的0开始,接下来的3的1,接下来的3的2,依此类推.我们使用此新列(+国家/地区)根据需要对数据进行分组.如果删除dplyr代码中最后一个管道部件,可以检查它.