计算以逗号分隔的值并在 R 中复制一个值相等的次数

Count comma delimited values and replicate a value equal times in R

给定以下示例数据...

id                               Proteins
522     Q9UHC7-4;Q9UHC7-3;Q9UHC7-2;Q9UHC7
523                                Q9UHV7
524                       Q9Y6T7-2;Q9Y6T7
525                       Q9Y6T7-2;Q9Y6T7

...我想创建第三列,每列 id 乘以每行的分号分隔值的数量。更具体地说是这样的:

id                               Proteins     newCol
522     Q9UHC7-4;Q9UHC7-3;Q9UHC7-2;Q9UHC7    522;522;522;522
523                                Q9UHV7    523
524                       Q9Y6T7-2;Q9Y6T7    524;524
525                       Q9Y6T7-2;Q9Y6T7    525;525

我试过这个 dt$newCol <- rep(dt$id, lengths(str_split(dt$Proteins, ";"))) 但不起作用,因为它会创建一个更长的列表。

library(tidyverse)

df %>%
  mutate(newCol = map2_chr(id, str_count(Proteins, ";") + 1, ~str_c(rep(.x, .y), collapse = ";")))

是这样的吗?

library(stringr)
df$newCol <- str_replace_all(df$Proteins, "[^;]+", as.character(df$id))

输出

> df
   id                          Proteins          newCol
1 522 Q9UHC7-4;Q9UHC7-3;Q9UHC7-2;Q9UHC7 522;522;522;522
2 523                            Q9UHV7             523
3 524                   Q9Y6T7-2;Q9Y6T7         524;524
4 525                   Q9Y6T7-2;Q9Y6T7         525;525

@markus

建议的另一个 Base R 解决方案
df1$new <- Map(gsub, pattern = "[^;]+", replacement = df1$id, x = df1$Proteins)

基本的 R 解决方案是计算 ";" 出现的次数,向其添加 +1,相应地重复 id。使用 tapply 将 id 粘贴在一起以创建 newCol.

x <- rep(df$id, lengths(regmatches(df$Proteins, gregexpr(";", df$Proteins))) + 1)
df$newCol <- tapply(x, x, paste0, collapse = ';')
df

#   id                          Proteins          newCol
#1 522 Q9UHC7-4;Q9UHC7-3;Q9UHC7-2;Q9UHC7 522;522;522;522
#2 523                            Q9UHV7             523
#3 524                   Q9Y6T7-2;Q9Y6T7         524;524
#4 525                   Q9Y6T7-2;Q9Y6T7         525;525

我们可以使用 for 循环 gsub

for(i in seq_len(nrow(df1))) df1$newCol[i] <- gsub("([[:alnum:]-]+)", df1$id[i], df1$Proteins[i])
df1
#  id                          Proteins          newCol
#1 522 Q9UHC7-4;Q9UHC7-3;Q9UHC7-2;Q9UHC7 522;522;522;522
#2 523                            Q9UHV7             523
#3 524                   Q9Y6T7-2;Q9Y6T7         524;524
#4 525                   Q9Y6T7-2;Q9Y6T7         525;525