基于R中的事件创建条件时间线

基于R中的事件创建条件时间线,r,dplyr,mutate,R,Dplyr,Mutate,我有“法律”变量表示不同地方(“地方”)立法变化的数据: 基本上,该法于1991年实施,并在随后的所有时期保持有效。它于1992年在B区实施并继续有效,等等 我想创建一个新变量,该变量在法律实施的年份取值为0,在法律实施后1年取值为1,在法律实施后2年取值为2,-在法律实施前1年取值为1,-在法律实施前2年取值为2,依此类推 我需要最终的数据帧如下所示: Person Place Year Law timeline 1 A 1990 0 -1 2

我有“法律”变量表示不同地方(“地方”)立法变化的数据:

基本上,该法于1991年实施,并在随后的所有时期保持有效。它于1992年在B区实施并继续有效,等等

我想创建一个新变量,该变量在法律实施的年份取值为0,在法律实施后1年取值为1,在法律实施后2年取值为2,-在法律实施前1年取值为1,-在法律实施前2年取值为2,依此类推

我需要最终的数据帧如下所示:

Person  Place  Year  Law  timeline 
1         A    1990   0     -1
2         A    1991   1      0
3         A    1992   1      1
4         B    1990   0     -2
5         B    1991   0     -1
6         B    1992   1      0
7         B    1993   1      1
8         B    1993   1      2
9         B    1993   1      2
10        B    1992   1      1
我试过:

library(dplyr)
df %>% 
 group_by(Place) %>%
 arrange(Year) %>%
 mutate(timeline = rank(Law))

但它没有像我需要的那样工作。我做错了什么?我可以在dplyr中执行此操作,还是需要创建一个复杂的for循环?

您可以通过执行
法则的索引减去
行数

df %>% 
    arrange(Year) %>% 
    group_by(Place) %>% 
    mutate(timeline = row_number() - which(diff(Law) == 1) - 1) %>% 
    arrange(Place)

# A tibble: 7 x 5
# Groups:   Place [2]
#  Person Place  Year   Law timeline
#   <int> <fct> <int> <int>    <dbl>
#1      1 A      1990     0      -1.
#2      2 A      1991     1       0.
#3      3 A      1992     1       1.
#4      4 B      1990     0      -2.
#5      5 B      1991     0      -1.
#6      6 B      1992     1       0.
#7      7 B      1993     1       1.
df%>%
安排(年)%>%
组别(地点)%>%
变异(时间线=行数()-其中(差异(定律)==1)-1)%>%
安排(地点)
#一个tibble:7x5
#分组:地点[2]
#人-地-年法律时间线
#          
#11a 1990年0-1。
#2 A 1991年1月10日。
#3 A 1992 1。
#4 B 1990 0-2。
#5 B 1991 0-1。
#6 B 1992年1月10日。
#7 B 1993 1。

使用
数据表

library(data.table)
setDT(dat)[,timeline:=sequence(.N)-which.min(!Law),by=Place]
dat
   Person Place Year Law timeline
1:      1     A 1990   0       -1
2:      2     A 1991   1        0
3:      3     A 1992   1        1
4:      4     B 1990   0       -2
5:      5     B 1991   0       -1
6:      6     B 1992   1        0
7:      7     B 1993   1        1
使用基本r:

transform(dat,timeline=ave(Law,Place,FUN=function(x)1:length(x)-which.min(!x)))
  Person Place Year Law timeline
1      1     A 1990   0       -1
2      2     A 1991   1        0
3      3     A 1992   1        1
4      4     B 1990   0       -2
5      5     B 1991   0       -1
6      6     B 1992   1        0
7      7     B 1993   1        1

也许
row\u number()-哪个.max(Law==1)
@Henrik更好!这不仅仅是代码高尔夫,它是闪电圆代码高尔夫。我似乎还记得几年(几十年)前的ACM编程竞赛,竞赛中出现了更复杂的问题,但最后一秒的提交/改进情况类似。不幸的是,我每年在每个地方都有许多观察结果,这意味着row_number()函数被无望地抛弃了。我想我的代码示例应该更清楚…在您的示例中,每个地点/年份组合只有一行。也许你可以用一个不同的例子来反映你的实际数据?
transform(dat,timeline=ave(Law,Place,FUN=function(x)1:length(x)-which.min(!x)))
  Person Place Year Law timeline
1      1     A 1990   0       -1
2      2     A 1991   1        0
3      3     A 1992   1        1
4      4     B 1990   0       -2
5      5     B 1991   0       -1
6      6     B 1992   1        0
7      7     B 1993   1        1