【问题标题】:Sum values based on their string ID根据字符串 ID 对值求和
【发布时间】:2021-12-13 17:52:07
【问题描述】:

我有一个由逗号分隔的字符串序列组成的数据框。例如:

df <- data.frame(patterns = c("CCDC127, HSF1, NDUFB9", "CCDC127, EXOC3, YIF1A", "EXOC3, NDUFB9, YIF1A"))
df
               patterns
1 CCDC127, HSF1, NDUFB9
2 CCDC127, EXOC3, YIF1A
3  EXOC3, NDUFB9, YIF1A

我有另一个数据框,其中每个字符串对应一个数值。例如:

df2 <- data.frame(strings = c("CCDC127", "HSF1", "NDUFB9", "EXOC3", "YIF1A"),
                   scores = c(10, 11, 12, 13, 14))
df2
  strings scores
1 CCDC127     10
2    HSF1     11
3  NDUFB9     12
4   EXOC3     13
5   YIF1A     14

我想根据第二个数据帧中的值计算第一个数据帧中每个模式的总和。例如:

patterns sum
1 CCDC127, HSF1, NDUFB9  33
2 CCDC127, EXOC3, YIF1A  37
3  EXOC3, NDUFB9, YIF1A  39

对于这个问题的任何指示和帮助,我将不胜感激。

谢谢! 奥尔哈

【问题讨论】:

  • rownames(df2) &lt;- df2$strings; sapply(strsplit(df$patterns, ", *"), function(p) sum(df2[p, "scores"]))

标签: r string sum


【解决方案1】:

您可以将strsplitsapplymatch 一起使用:

df$sum <- sapply(strsplit(df$patterns, ", "), 
                 function(x) sum(df2$scores[match(x, df2$strings)]))
df
#>                patterns sum
#> 1 CCDC127, HSF1, NDUFB9  33
#> 2 CCDC127, EXOC3, YIF1A  37
#> 3  EXOC3, NDUFB9, YIF1A  39

【讨论】:

    【解决方案2】:

    这是我确信会有一个超级智能应用解决方案的地方,但我会通过将df 表转换为查找表,然后将其加入并汇总来做到这一点。

    df %>%
      mutate(patterns2 = patterns) %>%
      separate(patterns2, paste("c", 1:3)) %>%
      pivot_longer(cols = paste("c", 1:3)) %>%
      #end of lookup creation, now join on
      right_join(df2, by = c("value" = "strings" )) %>%
      group_by(patterns) %>%
      summarise(scores = sum(scores))
    

    【讨论】:

      【解决方案3】:

      1) 将 df2 转换为一个命名列表 L 适合与 eval 一起使用,然后在用加号替换逗号后评估解析 pattern 形成的每个表达式。

      L <- with(df2, split(scores, strings))
      transform(df, sums = sapply(parse(text = gsub(",", "+", patterns)), eval, L))
      

      给予:

                     patterns sums
      1 CCDC127, HSF1, NDUFB9   33
      2 CCDC127, EXOC3, YIF1A   37
      3  EXOC3, NDUFB9, YIF1A   39
      

      2) 另一种方法是从模式中提取单词,从 (1) 中的 L 中查找它们,然后求和。

      library(gsubfn)
      transform(df, sums = sapply(strapply(patterns, "\\w+", x ~ L[[x]]), sum))
      

      【讨论】:

        【解决方案4】:

        我们可以在mutate 调用中使用tidyr::separaterowSums

        library(dplyr)
        library(tidyr)
        
        df%>%mutate(
          sum = df %>% separate(col=patterns, sep=', +', into=paste0('pattern', 1:3))%>%
          rowwise()%>%
          mutate(across(everything(), ~df2$scores[df2$strings==.x]))%>%
          rowSums())
        
                       patterns sum
        1 CCDC127, HSF1, NDUFB9  33
        2 CCDC127, EXOC3, YIF1A  37
        3  EXOC3, NDUFB9, YIF1A  39
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-04-14
          • 1970-01-01
          • 2019-09-25
          • 2017-04-19
          • 2022-01-24
          • 1970-01-01
          • 2020-09-27
          • 1970-01-01
          相关资源
          最近更新 更多