使用条件匹配分配新字符串

Assigning new strings with conditional match

我有一个关于有条件地用新字符串替换字符串的问题。

到目前为止,我把我的真实问题的简短版本放在了它的工作中,但是我需要一个更好的解决方案,因为真实数据中有很多行。

strings <- c("ca_A33","cb_A32","cc_A31","cd_A30")

基本上我想用replace_strings替换stringsstrings 中的第一项替换为 replace_strings 中的第一项。

replace_strings <- c("A1","A2","A3","A4")

所以最后的字符串应该是这样的

final string <- c("ca_A1","cb_A2","cc_A3","cd_A4")

我写了一些简单的函数assign_new

assign_new <- function(x){

  ifelse(grepl("A33",x),gsub("A33","A1",x),
  ifelse(grepl("A32",x),gsub("A32","A2",x),
  ifelse(grepl("A31",x),gsub("A31","A3",x),
  ifelse(grepl("A30",x),gsub("A30","A4",x),x))))

}

assign_new(strings)

[1] "ca_A1" "cb_A2" "cc_A3" "cd_A4"

好的,看来我们有解决办法了。但是可以说,如果我有 A1000 到 A1 并想将它们从 A1 替换为 A1000,我需要执行 1000 行 ifelse 语句。我们该如何解决?

如果你的向量被命令匹配,那么你可以使用:

> paste0(gsub("(.*_)(.*)","\1", strings ), replace_strings)
[1] "ca_A1" "cb_A2" "cc_A3" "cd_A4"

编辑:根据@Onyambu 的评论,删除 map2_chr 因为 paste 是矢量化函数。

foo <- function(x, y){
  x <- unlist(lapply(strsplit(x, "_"), '[', 1))
  paste(x, y, sep = "_"))
}

foo(strings, replace_strings)

x 为 strings,y 为 replace_strings。您首先在 _ 字符处拆分 strings 对象,然后粘贴相应的 replace_strings 对象。

编辑:

对于没有位置关系的对象,您可以创建一个引用 table(数据框、列表等)并匹配您的值。

reference_tbl <- data.frame(strings, replace_strings)

foo <- function(x){
  y <- reference_tbl$replace_strings[match(x, reference_tbl$strings)]
  x <- unlist(lapply(strsplit(x, "_"), '[', 1))
  paste(x, y, sep = "_")
}

foo(strings)

使用 dplyr 包:

strings <- c("ca_A33","cb_A32","cc_A31","cd_A30")
replace_strings <- c("A1","A2","A3","A4")
df <- data.frame(strings, replace_strings)

df <- mutate(rowwise(df),
             strings = gsub("_.*",
                            paste0("_", replace_strings),
                            strings)
             )

df <- select(df, strings)

输出:

# A tibble: 4 x 1
  strings
  <chr>  
1 ca_A1  
2 cb_A2  
3 cc_A3  
4 cd_A4  

可以使用regmatches。先用regexpr获取_后面的所有字符,然后如下图替换

`regmatches<-`(strings,regexpr("(?<=_).*",strings,perl = T),value=replace_strings)
[1] "ca_A1" "cb_A2" "cc_A3" "cd_A4"

不是最快的,但非常易于处理且易于维护:

for (i in 1:length(strings)) {
  strings[i] <- gsub("\d+$", i, strings[i])
}

"\d+$" 只匹配字符串末尾的任意数字。

另一种方式:

mapply(function(x,y) gsub("(\w\w_).*",paste0("\1",y),x),strings,replace_strings,USE.NAMES=FALSE)
# [1] "ca_A1" "cb_A2" "cc_A3" "cd_A4"