【问题标题】:concatenate strings using common identifier使用通用标识符连接字符串
【发布时间】:2026-02-12 01:50:02
【问题描述】:
s1 <- "A*01 ATG GCC GTC ATG GCG CCC CGA ACC CTC CTC CTG CTA CTC TCG GGG GCC CTG GCC"
s2 <- "A*01 TCC CAC TCC ATG AGG TAT TTC TTC ACA TCC GTG TCC CCC GGC CGC GGG GAG CCC"
s3 <- "A*01 TAC GTG GAC GAC ACG CAG TTC GTG CGG TTC GAC AGC GAC GCC GCG AGC CAG AAG"

如何使用标识符“A*01”连接这些字符串?

预期输出:

sT <- "A*01 ATG GCC GTC ATG GCG CCC CGA ACC CTC CTC CTG CTA CTC TCG GGG GCC CTG GCC TCC CAC TCC ATG AGG TAT TTC TTC ACA TCC GTG TCC CCC GGC CGC GGG GAG CCC TAC GTG GAC GAC ACG CAG TTC GTG CGG TTC GAC AGC GAC GCC GCG AGC CAG AAG"

【问题讨论】:

  • 您的预期输出是什么?
  • pastepaste0 是 R 中的主要字符串连接主力。我不确定“使用标识符 A*01”是什么意思。
  • 字符串中的第一个元素是标识符
  • 刚刚编辑,包括预期输出
  • 是否存在较大的数据结构或文件,其中包含许多带有A*01(和其他)前缀的行?即是否应该有一个更通用的解决方案,根据提交的前缀标准进行连接?

标签: r


【解决方案1】:

对于更通用的解决方案,我假设您有一个文件,其中包含一堆看起来像问题中的行。如果是这种情况,那么以下内容应该可以满足您的需求。

library(stringr)
library(plyr)

dat <- readLines(textConnection("A*01 ATG GCC GTC ATG GCG CCC CGA ACC CTC CTC CTG CTA CTC TCG GGG GCC CTG GCC
A*01 TCC CAC TCC ATG AGG TAT TTC TTC ACA TCC GTG TCC CCC GGC CGC GGG GAG CCC
A*01 TAC GTG GAC GAC ACG CAG TTC GTG CGG TTC GAC AGC GAC GCC GCG AGC CAG AAG
A*02 ATG GCC GTC ATG GCG CCC CGA ACC CTC CTC CTG CTA CTC TCG GGG GCC CTG GCC
A*02 TCC CAC TCC ATG AGG TAT TTC TTC ACA TCC GTG TCC CCC GGC CGC GGG GAG CCC
A*02 TAC GTG GAC GAC ACG CAG TTC GTG CGG TTC GAC AGC GAC GCC GCG AGC CAG AAG
A*03 ATG GCC GTC ATG GCG CCC CGA ACC CTC CTC CTG CTA CTC TCG GGG GCC CTG GCC
A*04 TCC CAC TCC ATG AGG TAT TTC TTC ACA TCC GTG TCC CCC GGC CGC GGG GAG CCC
A*04 TAC GTG GAC GAC ACG CAG TTC GTG CGG TTC GAC AGC GAC GCC GCG AGC CAG AAG"))


dat.df <- data.frame(prefix=str_match(dat, "(^A\\*[0-9]+) ")[,2],
                     sequence=str_match(dat, "\ (.*)$")[,2], stringsAsFactors=FALSE)

res <- daply(dat.df, .(prefix), .fun=function(x) {
  return(paste(x[1,]$prefix, paste(x$sequence, sep=" ", collapse=" "), 
               sep=" ", collapse=""))
})

names(res) <- NULL

print(res)

## [1] "A*01 ATG GCC GTC ATG GCG CCC CGA ACC CTC CTC CTG CTA CTC TCG GGG GCC CTG GCC TCC CAC TCC ATG AGG TAT TTC TTC ACA TCC GTG TCC CCC GGC CGC GGG GAG CCC TAC GTG GAC GAC ACG CAG TTC GTG CGG TTC GAC AGC GAC GCC GCG AGC CAG AAG"
## [2] "A*02 ATG GCC GTC ATG GCG CCC CGA ACC CTC CTC CTG CTA CTC TCG GGG GCC CTG GCC TCC CAC TCC ATG AGG TAT TTC TTC ACA TCC GTG TCC CCC GGC CGC GGG GAG CCC TAC GTG GAC GAC ACG CAG TTC GTG CGG TTC GAC AGC GAC GCC GCG AGC CAG AAG"
## [3] "A*03 ATG GCC GTC ATG GCG CCC CGA ACC CTC CTC CTG CTA CTC TCG GGG GCC CTG GCC"              
## [4] "A*04 TCC CAC TCC ATG AGG TAT TTC TTC ACA TCC GTG TCC CCC GGC CGC GGG GAG CCC TAC GTG GAC GAC ACG CAG TTC GTG CGG TTC GAC AGC GAC GCC GCG AGC CAG AAG"                                                                        

【讨论】:

  • 这是一个非常好的解决方案。非常感谢!
  • 只记得用文件名替换textConnection(…) 位:-)
  • 嗨 hrbmstr,这些正则表达式正在杀死我。如果标识符的类型是“A*01:01:01:01”、“A*01:01:01:02”、“A*01:01:01:02N”、“A*03:01”怎么办? :01:01"... 如何更改正则表达式 "(^A\*[0-9]+) " 以匹配此?
  • 正则表达式通常是一种神秘的魔法咒语。对于那些, "(^A\*[0-9\\:]+) 应该可以工作。我可能需要将其放入答案中,因为在 cmets 中似乎丢失了双重转义)。
【解决方案2】:
gsub(" A\\*01 ", " ", paste(s1, s2, s3, sep=" ", collapse=""))

在这种情况下会做你想做的事,但我怀疑从长远来看你可能需要一个更通用的解决方案。

【讨论】:

    【解决方案3】:

    试试这个

    > concat <- paste(s1, sub("A[*]01 ", "", s2), sub("A[*]01 ", "", s3))
    > identical(sT, concat)
    [1] TRUE
    

    concat 看起来像这样

    > concat
    [1] "A*01 ATG GCC GTC ATG GCG CCC CGA ACC CTC CTC CTG CTA CTC TCG GGG GCC CTG GCC TCC CAC TCC ATG AGG TAT TTC TTC ACA TCC GTG TCC CCC GGC CGC GGG GAG CCC TAC GTG GAC GAC ACG CAG TTC GTG CGG TTC GAC AGC GAC GCC GCG AGC CAG AAG"
    

    【讨论】: