【问题标题】:R- Trimming a string in a dataframe after a particular patternR-在特定模式之后修剪数据框中的字符串
【发布时间】:2017-08-29 20:04:50
【问题描述】:

我无法弄清楚如何修剪数据框中字符串的结尾。

我想将所有内容修剪为一个“基本”名称,在#s 和字母之后,一个句点,然后是一个数字。我的目标是将我的数据框中的所有内容都修剪为这个“基础”名称,然后将这些值与相同的“基础”相加。我在想有可能修剪,然后合并和求和这些值。

    ie/
    Gene_name   Values
    B0222.5     4
    B0222.6     16
    B0228.7.1   2
    B0228.7.2   12
    B0350.2h.1  30
    B0350.2h.2  2
    B0350.2i    15
    2RSSE.1a    3
    2RSSE.1b    10
    R02F11.11   4

    Gene_name   Values
    B0222.5     4
    B0222.6     16
    B0228.7     14
    B0350.2     47
    2RSSE.1     13
    R02F11.11   4

感谢您的帮助!

【问题讨论】:

  • 使用这个正则表达式 ([[:alnum:]]+\.[[:digit:]]+) (或 ([a-zA-Z0-9]+\.[0-9]+) - 两者是等效的)捕捉你的“基本”名称,然后根据匹配减少你的数组。正则表达式不能轻松执行计算(如果你设法让它工作,这不是真的可行,而且更像是一种黑客攻击)
  • 可能最简单的方法是使用正则表达式匹配创建一个新数组(默认值为 0),然后使用循环根据每个连续匹配添加到该数组键。我对 R 不熟悉,但这就是我在大多数其他语言中的工作方式。 a= [[B0222.5, 4], ..., [B0228.7.1, 2], [B0228.7.2, 12], ...] => 循环每个键/值对 => 第一个匹配 = B0222.5 => b=[[B0222.5, 4]] => ... => 第三个匹配 = B0228.7 => b = [[B0222.5, 4], ..., [B0228.7, 2]] => 第四个匹配 =@ 987654330@ => b = [[B0222.5, 4], ..., [B0228.7, 14]]

标签: r regex dataframe trim


【解决方案1】:

这是使用dplyrstringr 包的解决方案。您首先使用提取的基本模式创建一个列,然后使用 dplyr 中的 group_bysummarise 函数来获取每个名称的值的总和:

library(dplyr)
library(stringr)
df2 = df %>% mutate(Gene_name = str_extract(Gene_name,"[[:alnum:]]+\\.\\d+")) %>% 
group_by(Gene_name) %>% summarise(Values = sum(Values))

  Gene_name Values
      <chr>  <int>
1   2RSSE.1     13
2   B0222.5      4
3   B0222.6     16
4   B0228.7     14
5   B0350.2     47
6 R02F11.11      4

【讨论】:

    【解决方案2】:

    正如有人也建议的那样,我会先获取基因名称,然后在原始data.frame中搜索它们

    df <- data.frame(Gene_name = c("B0222.5", "B0222.6", "B0228.7.1",  "B0228.7.2", "B0350.2h.1", "B0350.2h.2", "B0350.2i", "2RSSE.1a", "2RSSE.1b", "R02F11.11"),
                     Values = c(4, 16, 2, 12, 30, 2, 15, 3, 10, 4),
                     stringsAsFactors = F)
    
    pat <- "(^[[:alnum:]]+\\.[[:digit:]]*)"
    cap.pos <- regexpr(pat,  df$Gene_name)
    cap.gene <- unique(substr(df$Gene_name, cap.pos, (cap.pos + attributes(cap.pos)$match.length - 1)))
    
    do.call(rbind, lapply(cap.gene, (function(nm){
      sumval <- sum(df[grepl(nm, df$Gene_name, fixed = T),]$Values, na.rm = T)
      data.frame(Gene_name = nm, Value = sumval)
    })))
    

    根据您的要求跟踪结果

      Gene_name Value
    1   B0222.5     4
    2   B0222.6    16
    3   B0228.7    14
    4   B0350.2    47
    5   2RSSE.1    13
    6 R02F11.11     4
    

    【讨论】:

      【解决方案3】:

      您还可以创建 Gene_name 作为因子并更改级别。

      # coerce the vector as a factor
      Gene_name <- as.factor(Gene_name)
      # view the levels
      levels(Gene_name)
      # to make B0228.7.1 into B0228.7
      levels(Gene_name)[ *index for B0228.7.1* ] <- B0228.7
      

      您可以对需要更改的级别重复此操作,然后值将自动汇总在一起,具有相似级别的行将被视为同一类别。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-04-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-23
        • 1970-01-01
        • 2014-11-27
        相关资源
        最近更新 更多