【问题标题】:R - add column that counts sequentially within groups but repeats for duplicatesR - 添加在组内按顺序计数但重复重复的列
【发布时间】:2015-03-09 20:34:54
【问题描述】:

我正在寻找一种解决方案来添加列“desired_result”,最好使用 dplyr 和/或 ave()。请参阅此处的数据框,其中组是“部分”,我希望我的“desired_results”列按顺序计数的唯一实例在“展览”中:

structure(list(section = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L), exhibit = structure(c(1L, 
2L, 3L, 3L, 1L, 2L, 2L, 3L), .Label = c("a", "b", "c"), class = "factor"), 
desired_result = c(1L, 2L, 3L, 3L, 1L, 2L, 2L, 3L)), .Names = c("section", 
"exhibit", "desired_result"), class = "data.frame", row.names = c(NA, 
-8L))

【问题讨论】:

  • df$desired <- c("a"=1, "b"=2, "c"=3)[df$exhibit]
  • 我认为您的“规则”不够清晰。您的数据是否已排序,就像您在此处的示例数据集中一样?
  • @Khashaa 抱歉,出于示例数据框的目的,我将全名缩短为单个字母。有很多名字,所以我需要处理更多的实例,而不仅仅是 3 个。
  • @Ananda Mahto,这些名称不是按字母顺序排列的,而是随机出现的,所以你是对的,我的数据框具有误导性。重要的部分是,当展览列中的计数达到重复时,它应该重复。

标签: r dataframe dplyr


【解决方案1】:

我最近将一个函数 rleid() 推送到 data.table(目前在开发版本 1.9.5 上可用),它正是这样做的。有兴趣的可以关注this安装。

require(data.table) # 1.9.5, for `rleid()`
require(dplyr)
DF %>% 
  group_by(section) %>% 
  mutate(desired_results=rleid(exhibit))

#   section exhibit desired_result desired_results
# 1       1       a              1               1
# 2       1       b              2               2
# 3       1       c              3               3
# 4       1       c              3               3
# 5       2       a              1               1
# 6       2       b              2               2
# 7       2       b              2               2
# 8       2       c              3               3

【讨论】:

  • 这会产生与 Khashaa 使用 dense_rank 的答案相同的结果吗?我还没有安装 data.table 1.9.5。
  • 对于有序数据,它返回与dense_rank 相同的值。一般来说,似乎rleid(x) 就像rep(1:length(rle(x)$values), rle(x)$lengths)
  • rleid() 也适用于超过 1 列。例如:with(DF, rleid(section, exhibit))
【解决方案2】:

dense_rank

library(dplyr)
df %>% 
  group_by(section) %>% 
  mutate(desire=dense_rank(exhibit))
#  section exhibit desired_result desire
#1       1       a              1      1
#2       1       b              2      2
#3       1       c              3      3
#4       1       c              3      3
#5       2       a              1      1
#6       2       b              2      2
#7       2       b              2      2
#8       2       c              3      3

【讨论】:

    【解决方案3】:

    如果需要精确枚举并且您希望结果保持一致(以便不同部分中的相同展览始终具有相同的编号),您可以尝试:

    library(dplyr)
    df <- data.frame(section = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L),
                     exhibit = c('a', 'b', 'c', 'c', 'a', 'b', 'b', 'c'))
    if (is.null(saveLevels <- levels(df$exhibit)))
        saveLevels <- sort(unique(df$exhibit)) ## or levels(factor(df$exhibit))
    df %>%
        group_by(section) %>%
        mutate(answer = as.integer(factor(exhibit, levels = saveLevels)))
    ## Source: local data frame [8 x 3]
    ## Groups: section
    ##   section exhibit answer
    ## 1       1       a      1
    ## 2       1       b      2
    ## 3       1       c      3
    ## 4       1       c      3
    ## 5       2       a      1
    ## 6       2       b      2
    ## 7       2       b      2
    ## 8       2       c      3
    

    如果/当新的exhibit 出现在随后的sections 中,他们应该得到新的枚举结果。 (注意最后一个exhibit 不同。)

    df2 <- data.frame(section = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L),
                      exhibit = c('a', 'b', 'c', 'c', 'a', 'b', 'b', 'd'))
    if (is.null(saveLevels2 <- levels(df2$exhibit)))
        saveLevels2 <- sort(unique(df2$exhibit))
    df2 %>%
        group_by(section) %>%
        mutate(answer = as.integer(factor(exhibit, levels = saveLevels2)))
    ## Source: local data frame [8 x 3]
    ## Groups: section
    ##   section exhibit answer
    ## 1       1       a      1
    ## 2       1       b      2
    ## 3       1       c      3
    ## 4       1       c      3
    ## 5       2       a      1
    ## 6       2       b      2
    ## 7       2       b      2
    ## 8       2       d      4
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-14
      相关资源
      最近更新 更多