使用条件匹配分配新字符串
Assigning new strings with conditional match
我有一个关于有条件地用新字符串替换字符串的问题。
到目前为止,我把我的真实问题的简短版本放在了它的工作中,但是我需要一个更好的解决方案,因为真实数据中有很多行。
strings <- c("ca_A33","cb_A32","cc_A31","cd_A30")
基本上我想用replace_strings
替换strings
。 strings
中的第一项替换为 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"
我有一个关于有条件地用新字符串替换字符串的问题。
到目前为止,我把我的真实问题的简短版本放在了它的工作中,但是我需要一个更好的解决方案,因为真实数据中有很多行。
strings <- c("ca_A33","cb_A32","cc_A31","cd_A30")
基本上我想用replace_strings
替换strings
。 strings
中的第一项替换为 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"