在数据帧中的组内按时间倒序编号生成(生成:0,-1,-2等)

BWo*_*olk 2 r dataframe

我正在使用一个数据框架,该数据框架包括不同的组,并且都有多年的范围。像这样:

df <- data.frame(group = c(rep("aaa", 3), rep("bbb", 3), rep("ccc", 3)), year = c(2016:2018))
df  

   group  year  
1  aaa    2016  
2  aaa    2017
3  aaa    2018
4  bbb    2016
5  bbb    2017
6  bbb    2018
7  ccc    2016
8  ccc    2017
9  ccc    2018  
Run Code Online (Sandbox Code Playgroud)

我想做的是创建一个列(世代),该列基于年份分配一个值,其中最新一代为0代,对于较老的代而言则倒数。像这样:

   group  year  generation
1  aaa    2018  0
2  bbb    2018  0
3  ccc    2018  0
4  aaa    2017  -1
5  bbb    2017  -1
6  ccc    2017  -1 
7  aaa    2016  -2
8  bbb    2016  -2
9  ccc    2016  -2
Run Code Online (Sandbox Code Playgroud)

我认为它必须类似于以下内容,但这给了我1到3而不是-2到0的范围:

df2 <- df %>% 
  group_by(group) %>% 
  arrange(desc(year)) %>% 
  mutate(generation = min_rank(year))
df2

   group  year  generation
1  aaa    2018  3
2  bbb    2018  3
3  ccc    2018  3
4  aaa    2017  2
5  bbb    2017  2
6  ccc    2017  2 
7  aaa    2016  1
8  bbb    2016  1
9  ccc    2016  1
Run Code Online (Sandbox Code Playgroud)

任何想法如何达到我想要的范围?谢谢!

Ron*_*hah 6

如果year并非总是连续的,则可以order year从组中的总行数中减去它。

library(dplyr)
df %>%
  group_by(group) %>%
  mutate(generation = -(n() - order(year))) %>%
  arrange(desc(year))

# group  year generation
#  <fct> <int>      <int>
#1 aaa    2018          0
#2 bbb    2018          0
#3 ccc    2018          0
#4 aaa    2017         -1
#5 bbb    2017         -1
#6 ccc    2017         -1
#7 aaa    2016         -2
#8 bbb    2016         -2
#9 ccc    2016         -2
Run Code Online (Sandbox Code Playgroud)

使用基数R将是

with(df, ave(year, group, FUN = function(x) -(length(x) - order(x))))
Run Code Online (Sandbox Code Playgroud)

如果year总是连续的,我们可以yearmax组中的年份中减去。

df %>%
  group_by(group) %>%
  mutate(generation = year - max(year))
Run Code Online (Sandbox Code Playgroud)

with(df, year - ave(year, group, FUN = max))
Run Code Online (Sandbox Code Playgroud)