【问题标题】:Sequence a column based on two other columns with a restarting sequence基于具有重新启动序列的其他两个列对列进行排序
【发布时间】:2023-12-27 20:03:02
【问题描述】:

我正在使用一个类似于下面的数据框,我想根据名称和年份计算或拥有一个 id,但是当名称更改时会重新启动。我看过很多帖子(123),但大多数都想要一个不可重启的标识符/计数器。

我认为 group_by 和 seq_along 会起作用,但 seq_along 只需要一个变量,所以这不起作用

df1 <- df %>% 
    group_by(name, year) %>%
    arrange(year) %>%
    mutate(
        exp = seq_along(c(name, year)))

我也尝试过将各种 data.table 序列与 .GRP 一起使用,例如以下无济于事

df1 <- data.table(df, key="name,year")
df1 <- df1[, Year_id :=.GRP, by=key(df1)]

这是一个示例数据框。

df <- data.frame(
  name = rep(c("A","B"), each=5), 
  year=rep(2000:2001, times=5), 
  stringsAsFactors=FALSE)

期望的输出:

       name year     Year_id
1        A 2000         1
2        A 2000         1
3        A 2000         1
4        A 2001         2
5        A 2001         2
6        B 2000         1
7        B 2000         1
8        B 2000         1
9        B 2001         2
10       B 2001         2

【问题讨论】:

  • 使用data.table,您可以尝试dt[,Year_id:=match(year,unique(year)),by=name]dt 是从您的data.frame 获得的data.table)。
  • @nicola 我可能会使用 .GRP,就像 Matt Dowle 在这里的回答:*.com/q/35371340

标签: r dataframe dplyr sequence


【解决方案1】:

1) dplyr 创建一个因子并提取其水平:

library(dplyr)
df %>% 
   arrange(name, year) %>% 
   group_by(name) %>%
   mutate(Year_id = as.numeric(factor(year))) %>%
   ungroup()

给予:

# A tibble: 10 x 3
    name  year Year_id
   <chr> <int>   <dbl>
1      A  2000       1
2      A  2000       1
3      A  2000       1
4      A  2001       2
5      A  2001       2
6      B  2000       1
7      B  2000       1
8      B  2001       2
9      B  2001       2
10     B  2001       2

1a) 根据@nicola 的评论,mutate 也可以写成mutate(Year_id = match(year, unique(year)))

2) 没有包 没有包也可以这样写:

o <- with(df, order(name, year))
transform(df[o, ], Year_id = ave(year, name, FUN = function(x) as.numeric(factor(x))))

或使用match

【讨论】:

    【解决方案2】:

    怎么样

    dat %>% 
      group_by(name) %>% 
      arrange(year) %>% 
      mutate(id = cumsum(c(1L, diff(year))))
    

    这给出了:

    Source: local data frame [10 x 4]
    Groups: name [2]
    
         name  year Year_id    id
       <fctr> <int>   <int> <int>
    1       A  2000       1     1
    2       A  2000       1     1
    3       A  2000       1     1
    4       A  2001       2     2
    5       A  2001       2     2
    6       B  2000       1     1
    7       B  2000       1     1
    8       B  2000       1     1
    9       B  2001       2     2
    10      B  2001       2     2
    

    【讨论】: