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