下面是一个dplyr
/tidyr
的方法:
library(dplyr)
library(tidyr) # unnest
df %>%
mutate(
last = sub(".*_", "", Column1),
mult = regmatches(last, gregexpr("[TYS][0-9]+", last))
) %>%
unnest(mult) %>%
mutate(Column1 = paste0(sub("_[^_]*$", "_", Column1), mult)) %>%
select(-last, -mult)
# # A tibble: 3 × 3
# Column1 Column2 Column3
# <chr> <chr> <chr>
# 1 A01235_414_429_2_2_Y414 C2 C3
# 2 A01235_414_429_2_2_T418 C2 C3
# 3 A01235_414_429_2_2_S687 C2 C3
使用tidyr::separate_rows
是可能的(需要更多的正则表达式和更多的工作),但是由于没有明确的定义,我认为它的代码量与上面的代码量大致相同(如果不是更多的话).
regmatches(last, gregexpr(..))
位在最后_
位之后的子串上操作,only位在那部分上操作;它的目的是提取任何以[TYS]
开头、后面跟一个或多个数字的子串.
查看前mutate(.)
个之后的结果,注意List-Column是什么(不是逗号分隔的字符串列),然后了解下面的unnest
和mutate
是如何清理数据的,这可能是有意义的.
Edit:这也适用于一个字符串中的重复字母,如
df <- structure(list(Column1 = c("A01235_414_429_2_2_Y414T418S687", "A2A123_1532_1541_2_2_S1532S1535"), Column2 = c("C2", "C2"), Column3 = c("C3", "C3")), class = "data.frame", row.names = c(NA, -2L))
df
# Column1 Column2 Column3
# 1 A01235_414_429_2_2_Y414T418S687 C2 C3
# 2 A2A123_1532_1541_2_2_S1532S1535 C2 C3
df %>%
mutate(
last = sub(".*_", "", Column1),
mult = regmatches(last, gregexpr("[TYS][0-9]+", last))
) %>%
unnest(mult) %>%
mutate(Column1 = paste0(sub("_[^_]*$", "_", Column1), mult)) %>%
select(-last, -mult)
# # A tibble: 5 × 3
# Column1 Column2 Column3
# <chr> <chr> <chr>
# 1 A01235_414_429_2_2_Y414 C2 C3
# 2 A01235_414_429_2_2_T418 C2 C3
# 3 A01235_414_429_2_2_S687 C2 C3
# 4 A2A123_1532_1541_2_2_S1532 C2 C3
# 5 A2A123_1532_1541_2_2_S1535 C2 C3