【问题标题】:Split strings of different lengths and paste in specific column in a dataframe based on match根据匹配拆分不同长度的字符串并粘贴到数据框中的特定列中
【发布时间】:2020-11-27 14:04:00
【问题描述】:

我有一个包含不同长度字符串的向量: 向量如下例所示:

TX <- c("d_Bacteria|g_Thermobaculum", "d_Bacteria|p_Acidobacteria|c_Acidobacteria subdivision|f_Vicinamibacteraceae|g_Luteitalea", "d_Bacteria|p_Acidobacteria|c_Acidobacteriia|o_Acidobacteriales|f_Acidobacteriaceae|g_Acidobacterium", "d_Bacteria|p_Acidobacteria|c_Acidobacteriia|o_Acidobacteriales|f_Acidobacteriaceae|g_Candidatus Koribacter", "d_Bacteria|p_Acidobacteria|c_Acidobacteriia|o_Acidobacteriales|f_Acidobacteriaceae|g_Granulicella", "d_Bacteria|p_Acidobacteria|c_Acidobacteriia|o_Acidobacteriales|f_Acidobacteriaceae|g_Terriglobus")

我需要制作一个数据框来根据分类注释划分每个字符串:“domain”,“phylum”,“class”,“order”,“family”,“genus”

我试过了:

taxon <- str_split(clade_names, "\\|", simplify = T)

它可以完美地分割它,但它会从左到右填充数据框,我需要根据分类级别填充它。

我相信我需要使用grepl 来匹配“d_”、“p_”、“c_”、“o_”、“f_”、“g_” 但我不知道如何正确编写它。

非常感谢您的帮助。

【问题讨论】:

  • 两个略显老套的解决方案思路: 1. 在 str_splitting 之后,您可以执行一些 if_else 命令来改变新变量等等。如“if_else(value 以 p_ 开头,则变量 p_ ... 为 value,否则 NA)”
  • 2.想法:在 str_splitting 之后,您可以将数据集旋转更长的时间,根据值更改创建的“名称”列的值,然后使用 pivot_wider 将其重新整形。
  • 另外,如果您能提供一个我们可以使用的最小可重现示例,而不仅仅是复制的输出,那就太好了。 stackoverflow.com/help/minimal-reproducible-example
  • 我更新了我所做的代码部分,因此可以重现它。 =)
  • 你可以使用我的“splitstackshape”包中的cSplit,拆分两次。 library(splitstackshape); cSplit(cSplit(as.data.table(TX)[, row := seq_along(TX)], "TX", "|", "long"), "TX", "_", "wide")[, dcast(.SD, row ~ TX_1, value.var="TX_2")]

标签: r dataframe strsplit


【解决方案1】:

使用data.table,在"|"上拆分,从宽到长进行reshape,然后在"_"上拆分得到分类注释组,然后从长到宽进行reshape:

library(data.table)

TX <- c("d_Bacteria|g_Thermobaculum", "d_Bacteria|p_Acidobacteria|c_Acidobacteria subdivision|f_Vicinamibacteraceae|g_Luteitalea", "d_Bacteria|p_Acidobacteria|c_Acidobacteriia|o_Acidobacteriales|f_Acidobacteriaceae|g_Acidobacterium", "d_Bacteria|p_Acidobacteria|c_Acidobacteriia|o_Acidobacteriales|f_Acidobacteriaceae|g_Candidatus Koribacter", "d_Bacteria|p_Acidobacteria|c_Acidobacteriia|o_Acidobacteriales|f_Acidobacteriaceae|g_Granulicella", "d_Bacteria|p_Acidobacteria|c_Acidobacteriia|o_Acidobacteriales|f_Acidobacteriaceae|g_Terriglobus")

taxon <- data.table(x = TX)

taxon[, tstrsplit(x, "|", fixed = TRUE)
      ][, rn := seq_len(.N)
        ][, melt(.SD, id.var = "rn")
          ][, c("grp", "name") := tstrsplit(value, "_")
            ][!is.na(value), dcast(.SD, rn ~ grp, value.var = "value")]
#    rn                           c          d                     f                       g                  o               p
# 1:  1                        <NA> d_Bacteria                  <NA>         g_Thermobaculum               <NA>            <NA>
# 2:  2 c_Acidobacteria subdivision d_Bacteria f_Vicinamibacteraceae            g_Luteitalea               <NA> p_Acidobacteria
# 3:  3            c_Acidobacteriia d_Bacteria   f_Acidobacteriaceae        g_Acidobacterium o_Acidobacteriales p_Acidobacteria
# 4:  4            c_Acidobacteriia d_Bacteria   f_Acidobacteriaceae g_Candidatus Koribacter o_Acidobacteriales p_Acidobacteria
# 5:  5            c_Acidobacteriia d_Bacteria   f_Acidobacteriaceae          g_Granulicella o_Acidobacteriales p_Acidobacteria
# 6:  6            c_Acidobacteriia d_Bacteria   f_Acidobacteriaceae           g_Terriglobus o_Acidobacteriales p_Acidobacteria

【讨论】:

    【解决方案2】:

    这是一个 tidyverse 解决方案(我猜你更喜欢它,因为你已经在使用 str_split 函数):

    library(tidyverse)
    TX <- data.frame(clade_names = c("d_Bacteria|g_Thermobaculum", "d_Bacteria|p_Acidobacteria|c_Acidobacteria subdivision|f_Vicinamibacteraceae|g_Luteitalea", "d_Bacteria|p_Acidobacteria|c_Acidobacteriia|o_Acidobacteriales|f_Acidobacteriaceae|g_Acidobacterium", "d_Bacteria|p_Acidobacteria|c_Acidobacteriia|o_Acidobacteriales|f_Acidobacteriaceae|g_Candidatus Koribacter", "d_Bacteria|p_Acidobacteria|c_Acidobacteriia|o_Acidobacteriales|f_Acidobacteriaceae|g_Granulicella", "d_Bacteria|p_Acidobacteria|c_Acidobacteriia|o_Acidobacteriales|f_Acidobacteriaceae|g_Terriglobus"))
    
    TX2 <- TX %>%
      mutate(splits = str_split(clade_names, "\\|")) %>%
      unnest_wider(splits) %>%
      pivot_longer(cols = -clade_names) %>%
      mutate(name = str_sub(value, 1, 2)) %>%
      filter(!is.na(name)) %>%
      pivot_wider()
    

    给出:

    # A tibble: 6 x 7
      clade_names                                        d_       g_           p_        c_            f_          o_        
      <chr>                                              <chr>    <chr>        <chr>     <chr>         <chr>       <chr>     
    1 d_Bacteria|g_Thermobaculum                         d_Bacte~ g_Thermobac~ NA        NA            NA          NA        
    2 d_Bacteria|p_Acidobacteria|c_Acidobacteria subdiv~ d_Bacte~ g_Luteitalea p_Acidob~ c_Acidobacte~ f_Vicinami~ NA        
    3 d_Bacteria|p_Acidobacteria|c_Acidobacteriia|o_Aci~ d_Bacte~ g_Acidobact~ p_Acidob~ c_Acidobacte~ f_Acidobac~ o_Acidoba~
    4 d_Bacteria|p_Acidobacteria|c_Acidobacteriia|o_Aci~ d_Bacte~ g_Candidatu~ p_Acidob~ c_Acidobacte~ f_Acidobac~ o_Acidoba~
    5 d_Bacteria|p_Acidobacteria|c_Acidobacteriia|o_Aci~ d_Bacte~ g_Granulice~ p_Acidob~ c_Acidobacte~ f_Acidobac~ o_Acidoba~
    6 d_Bacteria|p_Acidobacteria|c_Acidobacteriia|o_Aci~ d_Bacte~ g_Terriglob~ p_Acidob~ c_Acidobacte~ f_Acidobac~ o_Acidoba~
    

    您当然可以进一步调整此代码以提供更有意义的名称或从 clade_names 等中删除 X_ 部分。

    【讨论】:

      猜你喜欢
      • 2020-06-11
      • 2016-08-21
      • 2021-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多