R语言 如何基于字符串模式连接同一列中的字符串?

t5zmwmid  于 2023-06-27  发布在  其他
关注(0)|答案(2)|浏览(195)

我有一个dataframe,它有一个列,看起来像这样:
data.frame(sample_name = c("Sample01", "g01", "g02", "g03", "Sample02", "g01", "g02", "Sample03", "g03", "g04", "g07"))
我试着让它看起来像这样:
data.frame(sample_name = c("Sample01_g01", "Sample01_g02", "Sample01_g03", "Sample02_g01", "Sample02_g02", "Sample03_g03", "Sample03_g04", "Sample03_g07"))
问题是样本编号(例如g 01,g 02)从来不按任何数字顺序排列,并且具有不同的行数(“g”前缀总是在那里!)。所以,我需要这段代码足够灵活,可以处理输入,而不需要硬编码任何东西。
我尝试了几个for循环,基于正则表达式的模式匹配,并尝试分配分组变量来进行组拆分。我知道我想让它做什么,但我有麻烦将其转换为代码。这是我希望我的代码做的“英语”(而不是代码)版本:
1.基于regex标识样本名称(如"[A-Z][a-z]+[0-9]{2}"
1.从样品名称之后的行选择,直到下一个样品名称之前的行(例如,所有样品编号)
1.取步骤1中的样品名称,用下划线将其与已识别的样品编号连接起来,并保存到新列中
我试过Base R和Tidyverse。我通常更喜欢Tidyverse解决方案,但我渴望任何东西!谢谢你的帮助!

tquggr8v

tquggr8v1#

这样做的一种方法是:

library(dplyr)
library(tidyr)

df %>%
  mutate(sample_prefix = ifelse(grepl("^Sample", sample_name), sample_name, NA)) %>%
  fill(sample_prefix) %>%
  mutate(sample_name = ifelse(!grepl("^Sample", sample_name), paste(sample_prefix, sample_name, sep = "_"), sample_name), .keep="unused") %>%
  filter(grepl("_", sample_name))
sample_name
1 Sample01_g01
2 Sample01_g02
3 Sample01_g03
4 Sample02_g01
5 Sample02_g02
6 Sample03_g03
7 Sample03_g04
8 Sample03_g07
t40tm48m

t40tm48m2#

您可以尝试cumsum + ave + na.omit如下

na.omit(
    transform(
        df,
        sample_name = ave(
            sample_name,
            cumsum(startsWith(sample_name, "Sample")),
            FUN = \(x) c(NA, paste0(x[1], "_", x[-1]))
        )
    )
)

它给出了

sample_name
2  Sample01_g01
3  Sample01_g02
4  Sample01_g03
6  Sample02_g01
7  Sample02_g02
9  Sample03_g03
10 Sample03_g04
11 Sample03_g07

相关问题