我有以下数据框:
bla = data.frame(mycol = "bla_v2_2072|ID:61462952|;bla_v2_0113|ID:61460993|")
我想删除第一个“|”之后的所有内容,但该单元格基本上包含两个由“;”分隔的子字符串。
现在,我试过了
gsub("\\|.*","",bla$mycol)
这给了我
bla_v2_2072
,但我期望的是
bla_v2_2072;bla_v2_0113
我们可以用
library(dplyr)
library(tidyr)
library(stringr)
bla %>%
mutate(rn = row_number()) %>%
separate_longer_delim(mycol, delim = ";") %>%
reframe(mycol = str_c(str_remove(mycol, "\\|.*"),
collapse = ";"), .by = 'rn') %>%
select(-rn)
-输出
mycol
1 bla_v2_2072;bla_v2_0113
或使用
base R
gsub("(\\w+)(\\|ID:\\d+\\|)", "\\1", bla$mycol)
[1] "bla_v2_2072;bla_v2_0113"
使用
gsub()
:
bla$mycol <- gsub("(\\|.*?(?=;))|(\\|[^;]*$)", "", bla$mycol, perl = TRUE)
或者在 tidyverse 中使用相同的正则表达式模式:
library(dplyr)
library(stringr)
bla %>%
mutate(mycol = str_remove_all(mycol, "(\\|.*?(?=;))|(\\|[^;]*$)"))
结果:
mycol
1 bla_v2_2072;bla_v2_0113
说明:
"(\\|.*?(?=;)) # literal '|' and following characters up to next ';'
| # or
(\\|[^;]*$)" # literal '|' through end of string if no intervening ';'
gsub("\\|[^|]+\\|", "", bla$mycol)
#> [1] "bla_v2_2072;bla_v2_0113"
模式解释:转义“|”其次是一切不是“|”至少一次然后再“|”
你可以先用“;”分隔你的字符串然后删除“|”之后的所有内容。最后,使用
paste0
. 将它们连接起来
> paste0(sub("\\|.*","", unlist(strsplit(bla$mycol, split=";"))), collapse = "; ")
[1] "bla_v2_2072; bla_v2_0113"