【问题标题】:How to count instances of duplicate characters within a string?如何计算字符串中重复字符的实例?
【发布时间】:2025-11-21 23:15:01
【问题描述】:

我有一个数据框:

levels     counts
1, 2, 2        24
1, 2           20
1, 3, 3, 3     15
1, 3           10
1, 2, 3        25

例如,我想将“1,2,2”和“1,2”视为同一事物。所以,只要有一个“1”和“2”,没有任何其他字符,就会算作“1、2”级。这是所需的数据框:

levels     counts
  1, 2         44
  1, 3         25
  1, 2, 3      25

这里是重现原始数据框的代码:

df <- data.frame(levels = c("1, 2, 2", "1, 2", "1, 3, 3, 3", "1, 3", "1, 2, 3"), 
                 counts = c(24, 20, 15, 10, 25))
df$levels <- as.character(df$levels)

【问题讨论】:

  • 你研究过套装吗? set 数据结构不存储重复元素,对您的问题有好处。

标签: r duplicates character


【解决方案1】:

拆分df$levels,获取唯一元素,然后排序。然后用它来获取counts的聚合。

df$levels2 = sapply(strsplit(df$levels, ", "), function(x)
    paste(sort(unique(x)), collapse = ", "))   #Or toString(sort(unique(x))))
aggregate(counts~levels2, df, sum)
#  levels2 counts
#1    1, 2     44
#2 1, 2, 3     25
#3    1, 3     25

【讨论】:

    【解决方案2】:

    解决方案使用tidyversedf2 是最终输出。

    library(tidyverse)
    
    df2 <- df %>%
      mutate(ID = 1:n()) %>%
      mutate(levels = strsplit(levels, split = ", ")) %>%
      unnest() %>%
      distinct() %>%
      arrange(ID, levels) %>%
      group_by(ID, counts) %>%
      summarise(levels = paste(levels, collapse = ", ")) %>%
      ungroup() %>%
      group_by(levels) %>%
      summarise(counts = sum(counts))
    

    更新

    基于下面的cmet,一个使用类似于d.b的思路的解决方案

    df2 <- df %>% 
      mutate(l2 = map_chr(strsplit(levels, ", "), 
                          .f = ~ .x %>% unique %>% sort %>% toString)) %>%
      group_by(l2) %>% 
      summarise(counts = sum(counts))
    

    【讨论】:

    • 或者更直接的翻译自@d.b:df %&gt;% group_by(levels2 = strsplit(levels, ", ") %&gt;% sapply(. %&gt;% unique %&gt;% sort %&gt;% toString)) %&gt;% summarise(counts = sum(counts))
    • @Frank 也许我们可以将sapply 替换为更整洁的map_chr().. 类似:df %&gt;% group_by(l2 = map_chr(strsplit(levels, ","), .f = ~ .x %&gt;% unique %&gt;% sort %&gt;% toString)) %&gt;% summarise(counts = sum(counts))
    • @StevenBeaupré 感谢 cmets。我已根据您和弗兰克的建议更新了我的帖子。
    • @ycw 可以跳过mutate()直接使用group_by(l2 = ...)
    • @StevenBeaupré 我知道。感谢您展示这一点。我只是不希望group_by 通话时间过长。有时最好显示中间步骤。