【问题标题】:Cumulative count for interspersed categorical values in a dataframe, independently for each id [duplicate]数据框中散布的分类值的累积计数,独立于每个 id [重复]
【发布时间】:2019-11-30 11:13:45
【问题描述】:

我的数据有一列包含散布的冗余分类值。我想在每一行中指出每个唯一值出现的 ith 次。为了增加复杂性,我的数据框中有不同的 id,并且每个 id 的计数必须是独立的。

我的数据的虚拟版本

set.seed(123)
fruits <- sample(c("apple", "banana", "orange"), 30, replace = TRUE)
id <- c(rep(1, 10), rep(2, 10), rep(3, 10))
df <- as.data.frame(cbind(id, fruits))

> df
   id fruits
1   1 orange
2   1 orange
3   1 orange
4   1 banana
5   1 orange
6   1 banana
7   1 banana
8   1 banana
9   1 orange
10  1  apple
11  2 banana
12  2 banana
13  2  apple
14  2 banana
15  2 orange
16  2  apple
17  2 orange
18  2 orange
19  2  apple
20  2  apple
21  3  apple
22  3  apple
23  3 orange
24  3 banana
25  3 orange
26  3 banana
27  3  apple
28  3 banana
29  3 orange
30  3 banana

我正在寻找的输出

> df
   id fruits   fruit_repetitions_per_id  
1   1 orange   1
2   1 orange   2
3   1 orange   3
4   1 banana   1
5   1 orange   4
6   1 banana   2
7   1 banana   3
8   1 banana   4
9   1 orange   5
10  1  apple   1
11  2 banana   1
12  2 banana   2
13  2  apple   1
14  2 banana   3
15  2 orange   1
16  2  apple   2
17  2 orange   2
18  2 orange   3
19  2  apple   3
20  2  apple   4
21  3  apple   1
22  3  apple   2
23  3 orange   1
24  3 banana   1
25  3 orange   2
26  3 banana   2
27  3  apple   3
28  3 banana   3
29  3 orange   3
30  3 banana   4

解决问题的尝试

  1. This one 几乎是我想要的,但我还需要为每个 id 分别计数/标记,该解决方案没有解决这个问题。

  2. This one 正是我所需要的,但无法使其工作并获得了一堆 NA:

with(df, ave(fruits, id,
             FUN = function(x) cumsum(!duplicated(x))))

[1] <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA>
Levels: apple banana orange
Warning messages:
1: In `[<-.factor`(`*tmp*`, i, value = c(1L, 1L, 1L, 2L, 2L, 2L, 2L,  :
  invalid factor level, NA generated
2: In `[<-.factor`(`*tmp*`, i, value = c(1L, 1L, 2L, 2L, 3L, 3L, 3L,  :
  invalid factor level, NA generated
3: In `[<-.factor`(`*tmp*`, i, value = c(1L, 1L, 2L, 3L, 3L, 3L, 3L,  :
  invalid factor level, NA generated

有什么想法吗?

谢谢!

【问题讨论】:

  • df$x &lt;- ave(df$id, df$id, df$fruits, FUN=seq_along)
  • @jogo,你的回答是最简单最简洁的。让它成为一个答案。
  • 问题已关闭,因为它是重复的(不可能有新的答案)。 stackoverflow.com/questions/12925063/… 的问题也有类似的答案
  • @jogo,通过测试您的解决方案,在 NA 值方面似乎存在故障。也就是说,如果df$fruits 包含相同df$id 的一些NA 值,ave() 会将两个 NA 标记为第一次出现。使用此处提出的@IceCreamToucan 或@akrun 的解决方案时,可以避免这种不需​​要的行为。我不确定为什么 NA 会破坏 ave() 而不是其他方法。想法?

标签: r


【解决方案1】:

您可以使用data.table::rowid

library(data.table)
setDT(df)

df[, new_col := rowid(id, fruits)]

【讨论】:

    【解决方案2】:

    您可以在 base 中执行此操作,因为您已经尝试使用 ave:

    df$fruit_repetitions_per_id  <- ave(rep(1,nrow(df)), df[c("id", "fruits")], FUN=cumsum)
    df
    #   id fruits fruit_repetitions_per_id
    #1   1 orange                        1
    #2   1 orange                        2
    #3   1 orange                        3
    #4   1 banana                        1
    #5   1 orange                        4
    #6   1 banana                        2
    #7   1 banana                        3
    #8   1 banana                        4
    #9   1 orange                        5
    #10  1  apple                        1
    #11  2 banana                        1
    #12  2 banana                        2
    #13  2  apple                        1
    #14  2 banana                        3
    #15  2 orange                        1
    #16  2  apple                        2
    #17  2 orange                        2
    #18  2 orange                        3
    #19  2  apple                        3
    #20  2  apple                        4
    #21  3  apple                        1
    #22  3  apple                        2
    #23  3 orange                        1
    #24  3 banana                        1
    #25  3 orange                        2
    #26  3 banana                        2
    #27  3  apple                        3
    #28  3 banana                        3
    #29  3 orange                        3
    #30  3 banana                        4
    

    【讨论】:

      【解决方案3】:

      一个选项是

      library(dplyr)
      df %>%
          group_by(id, fruits) %>%
          mutate(fruits_rep = row_number())
      

      【讨论】:

      • 谢谢,@akrun。在我的真实数据集中,我尝试使用mutate_at() 而不是mutate() 来更新现有列。但是,我不确定如何正确编写语法。我试过用vars() 包装,比如mutate_at(vars(fruits) = row_number()),但是没有用。 mutate_at(vars(fruits) , row_number()) 也没有。任何想法?谢谢
      • @Emman 这是mutate(fruits = row_number())
      猜你喜欢
      • 2012-04-19
      • 1970-01-01
      • 2018-03-15
      • 2019-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-08
      相关资源
      最近更新 更多