【问题标题】:tidyr: separate column while retaining delimiter in the first columntidyr:分隔列,同时在第一列中保留分隔符
【发布时间】:2021-07-28 07:34:21
【问题描述】:

我有一个列,我试图在保留分隔符的同时将其分成两列。我已经做到了这一点,但是分隔符的一部分被删除了。我还需要第二次拆分,将分隔符添加到我不知道该怎么做的第一列。

duplicates <- data.frame(sample = c("a_1_b1", "a1_2_b1", "a1_c_1_b2"))

duplicates <- separate(duplicates, 
                       sample, 
                       into = c("strain", "sample"),
                       sep = "_(?=[:digit:])")

仅以名字为例,我的输出是a_1b1,而我想要的输出是a_1_b1

我还想在第一列添加分隔符来执行此拆分,如下所示。

sample batch
a_1_ b1
a1_2_ b1
a1_c_1_ b2

编辑:This post 没有回答我的问题,即如何保留分隔符,或控制它在分割的哪一侧结束。

【问题讨论】:

  • 虽然那个骗子没有回答,但separate 提出的问题有100多个,我相信之前已经回答过

标签: r tidyr delimiter


【解决方案1】:
  1. 更新:请参阅 cmets 中的 OP 请求:
duplicates %>% 
    mutate(batch = sub(".*_", "_", sample)) %>%  
    mutate(sample = sub("_[^_]+$", "", sample))

输出:

  sample batch
1    a_1   _b1
2   a1_2   _b1
3 a1_c_1   _b2

澄清后更新:见 cmets:

duplicates %>% 
    mutate(batch = sub(".*_", "", sample)) %>%  
    mutate(sample = sub("_[^_]+$", "_", sample))

输出:

   sample batch
1    a_1_    b1
2   a1_2_    b1
3 a1_c_1_    b2

第一个答案: 我们可以使用来自stringr 包的str_sub

library(stringr)
library(dplyr)

duplicates %>% 
    mutate(batch = str_sub(sample, -2,-1)) %>% 
    mutate(sample = str_sub(sample, end=-3))

输出:

   sample batch
1    a_1_    b1
2   a1_2_    b1
3 a1_c_1_    b2

【讨论】:

  • 数字代表什么?
  • -2 = 最后两个字符。 -1 从字符串末尾开始。 -3 字符串的最后三个字符。
  • 我应该提供更准确的数据表示。我有时有 b10 值。
  • 请看我的更新。现在它应该更通用了!
  • 如何编辑它以接收相反的开关(a_1 和 _b1)?我对如何使用一些 R 表达式还有点不确定。
【解决方案2】:

使用separate

library(tidyr)
separate(duplicates, sample, into = c("strain", "sample"), 
        sep = "(?<=_)(?=[^_]+$)") 

-输出

    strain sample
1    a_1_     b1
2   a1_2_     b1
3 a1_c_1_     b2

用于拆分其他方式

separate(duplicates, sample, into = c("strain", "sample"), 
         sep = "(?<=[^_])(?=_[^_]+$)")
  strain sample
1    a_1    _b1
2   a1_2    _b1
3 a1_c_1    _b2

【讨论】:

    【解决方案3】:

    您可以将tidyr::extract 与捕获组一起使用。

    tidyr::extract(duplicates, sample, c("strain", "sample"), '(.*_)(\\w+)')
    
    #   strain sample
    #1    a_1_     b1
    #2   a1_2_     b1
    #3 a1_c_1_     b2
    

    同样的正则表达式也可以用于基础 R 中的 strcapture -

    strcapture('(.*_)(\\w+)', duplicates$sample, 
               proto = list(strain = character(), sample = character()))
    

    【讨论】:

    • 第一个解决方案对我有用。第二个创建了一个名为 sample 的空列并将整个字符串分配给应变。我将如何编辑它以实现相反的拆分(a_1 和 _b1)?
    • 对于您共享的数据,第二种解决方案似乎对我同样有效。
    • 我的实际数据格式略有不同,所以我猜这就是它不起作用的原因。我意识到第二列实际上并不是空的。使用实际列名而不是我给出的简化示例,将其分隔为 LEW_3_batch01(这是第 10 批)或 LEW_2_batch8
    • 我怎样才能调整第一个解决方案来给我相反的分裂?
    • 喜欢这个? tidyr::extract(duplicates, sample, c("strain", "sample"), '(.*?)(_.*)')
    猜你喜欢
    • 1970-01-01
    • 2019-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-31
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    相关资源
    最近更新 更多