如何为r中的嵌套组创建组索引

如何为r中的嵌套组创建组索引,r,R,我有一个数据集,其中包含嵌套在个人中的多个观察值。此示例数据集包括id列和星期几列(dayweek,1-7)。我对每个人进行了3天的观察。因此,一个人可能只提交了Sun/Wed/Thu(1,4,5)的报告,而另一个人可能提交了Sun/Mon/Tue(1,2,3)的报告,如本例所示: df我们可以按id分组,并为每个工作日创建一个唯一的id library(dplyr) df %>% group_by(id) %>% mutate(daynum = as.integer(fa

我有一个数据集,其中包含嵌套在个人中的多个观察值。此示例数据集包括id列和星期几列(dayweek,1-7)。我对每个人进行了3天的观察。因此,一个人可能只提交了Sun/Wed/Thu(1,4,5)的报告,而另一个人可能提交了Sun/Mon/Tue(1,2,3)的报告,如本例所示:


df我们可以
id
分组,并为每个
工作日创建一个唯一的
id

library(dplyr)

df %>%
  group_by(id) %>%
  mutate(daynum = as.integer(factor(dayweek, levels = unique(dayweek))))

#      id dayweek daynum
#   <dbl>   <dbl>  <int>
# 1     1       1      1
# 2     1       1      1
# 3     1       4      2
# 4     1       4      2
# 5     1       5      3
# 6     1       5      3
# 7     2       1      1
# 8     2       1      1
# 9     2       2      2
#10     2       2      2
#11     2       3      3
#12     2       3      3
#13     2       3      3
dplyr
使用
cumsum
!使用dplyr复制的

df %>%
  group_by(id) %>%
  mutate(daynum = cumsum(!duplicated(dayweek)))


# A tibble: 13 x 3
# Groups:   id [2]
      id dayweek daynum
   <dbl>   <dbl>  <int>
 1     1       1      1
 2     1       1      1
 3     1       4      2
 4     1       4      2
 5     1       5      3
 6     1       5      3
 7     2       1      1
 8     2       1      1
 9     2       2      2
10     2       2      2
11     2       3      3
12     2       3      3
13     2       3      3
根据,行是按顺序排列的

然后,这里有两种不同的方法也将处理评论中提到的“星期五、星期六、星期天”案例(
dayweek
6、7、1)

  • rleid()
  • fct\u顺序()
  • rleid()
    这将使用
    数据表中的
    rleid()
    函数

    library(dplyr)
    df2 %>% 
      group_by(id) %>% 
      mutate(daynum2 = data.table::rleid(dayweek)) 
    
    输出与上面相同

    资料 这是一个扩展数据集,还包括“星期五、星期六、星期日”案例(
    dayweek
    6、7、1):


    df2如果是星期五、星期六、星期天怎么办:那么你会有6、7、1,但6是第一天,1是第三天,对吗?行是否已按日期顺序排列,以便id的第一行将获得daynum=1?您好,正确:在这种情况下,我希望重新编码6到1、7到2和1到3。是的,行是按顺序排列的,但每个人每天的观察次数不同。因此,他们可能对Sat有4个观测值,对Sun有2个观测值,等等。对于“周五、周六、周日”案例(
    dayweek
    6、7、1),这将返回2、3、1,而OP根据评论预计会有1、2、3。@Uwe谢谢,更新了解决该案例的答案。
    unique
    的使用很有趣。不知怎的,
    !重复的
    很容易被理解为“唯一的”
    ,但应用它会变得很棘手。@NelsonGon是的,这里OP希望根据观察到的
    dayweek
    的时间遵循正确的顺序,因此,使用了
    唯一的
    。这也很好地处理了“星期五、星期六、星期天”的情况(
    dayweek
    6、7、1)。
    df %>%
      group_by(id) %>%
      mutate(daynum = cumsum(!duplicated(dayweek)))
    
    
    # A tibble: 13 x 3
    # Groups:   id [2]
          id dayweek daynum
       <dbl>   <dbl>  <int>
     1     1       1      1
     2     1       1      1
     3     1       4      2
     4     1       4      2
     5     1       5      3
     6     1       5      3
     7     2       1      1
     8     2       1      1
     9     2       2      2
    10     2       2      2
    11     2       3      3
    12     2       3      3
    13     2       3      3
    
    unlist(tapply(df$dayweek, df$id, function(x) cumsum(!duplicated(x))))
    
     1  1  2  2  3  3  1  1  2  2  3  3  3 
    
    library(dplyr)
    df2 %>% 
      group_by(id) %>% 
      mutate(daynum2 = data.table::rleid(dayweek)) 
    
          id dayweek daynum daynum2
       <dbl>   <dbl>  <dbl>   <int>
     1     1       1      1       1
     2     1       1      1       1
     3     1       4      2       2
     4     1       4      2       2
     5     1       5      3       3
     6     1       5      3       3
     7     2       1      1       1
     8     2       1      1       1
     9     2       2      2       2
    10     2       2      2       2
    11     2       3      3       3
    12     2       3      3       3
    13     2       3      3       3
    14     3       6      1       1
    15     3       7      2       2
    16     3       1      3       3
    
    df2 %>% 
      group_by(id) %>% 
      mutate(daynum2 = 
               dayweek %>% 
               as.character() %>% 
               forcats::fct_inorder() %>% 
               as.integer()
             ) 
    
    df2 <- data.frame(
      id = c(rep(1:2, each = 6), 2, rep(3, 3)),
      dayweek = c(rep(c(1, 4, 5), each = 2),rep(c(1, 2, 3), each = 2), 3, 6, 7, 1),
      daynum = c(rep(1:3, each = 2, times = 2), 3, 1:3)
    )