在特殊字符前匹配字符串 [英] Match strings before special character
问题描述
我正在尝试匹配两列中的字符串,并在:之前返回不匹配项。如果x2x,y67y不返回,因为x仍然是x,y仍然是y。
I am trying to match strings in two columns and return mismatches before ":". It should not return if x2x, y67y, as x remains x and y remains as y.
我不想匹配:decimal。如果x2y都在两列中,则表示匹配(无论特殊字符后的小数点不匹配)
INPUT:
I don't want to match the ":decimal". If x2y is in both columns then its a match (irrespective of the mismatch in the decimal after special character) INPUT:
input <- structure(list(x = structure(c(1L, 2L, 3L, 3L), .Label = c("A",
"B", "C"), class = "factor"), y = structure(c(2L, 3L, 1L, 4L), .Label = c("A",
"B", "C", "D"), class = "factor"), x_val = c("x2x:0.12345,y67h:0.06732,d7j:0.032647",
"x2y:0.26345,y67y:0.28320,d7r:0.043647", "x2y:0.23435,y67y:0.28310,d7r:0.043547",
"x2y:0.23435,y67y:0.28330,d7r:0.043247"), y_val = c("x2y:0.33134,y67y:0.3131,d7r:0.23443",
"x2y:0.34311,y67y:0.14142,d7r:0.31431", "x2x:0.34314,y67h:0.14141,d7j:0.453145",
"x67b:0.31411,g72v:0.3134,b8c:0.89234")), row.names = c(NA, -4L
), class = "data.frame")
输出:
output <- structure(list(x = structure(c(1L, 2L, 3L, 3L), .Label = c("A",
"B", "C"), class = "factor"), y = structure(c(2L, 3L, 1L, 4L), .Label = c("A",
"B", "C", "D"), class = "factor"), x_val = c("x2x:0.12345,y67h:0.06732,d7j:0.032647",
"x2y:0.26345,y67y:0.28320,d7r:0.043647", "x2y:0.23435,y67y:0.28310,d7r:0.043547",
"x2y:0.23435,y67y:0.28330,d7r:0.043247"), y_val = c("x2y:0.33134,y67y:0.3131,d7r:0.23443",
"x2y:0.34311,y67y:0.14142,d7r:0.31431", "x2x:0.34314,y67h:0.14141,d7j:0.453145",
"x67b:0.31411,g72v:0.3134,b8c:0.89234"), diff_x = c("y67h:0.06732,d7j:0.03264",
NA, "x2y:0.23435,d7r:0.043547", "x2y:0.23435,y67y:0.28330,d7r:0.043247"
), diff_y = c("x2y:0.33134,d7r:0.23443", NA, "y67h:0.14141,d7j:0.453145",
"x67b:0.31411,g72v:0.3134,b8c:0.89234")), row.names = c(NA, -4L
), class = "data.frame")
我只想匹配到:字符时遇到问题。以下代码是从该问题中获取的: https://stackoverflow.com/a/55285959/5150629 。
I run into problem when I just want to match till ":" character. The following code is taken from this question: https://stackoverflow.com/a/55285959/5150629.
library(dplyr)
library(purrr)
I %>% mutate(diff_x = map2_chr(strsplit(x_val, split = ", "),
strsplit(y_val, split = ", "),
~paste(grep('([a-z])(?>\\d+)(?!\\1)', setdiff(.x, .y),
value = TRUE, perl = TRUE),
collapse = ", ")) %>%
replace(. == "", NA),
diff_y = map2_chr(strsplit(x_val, split = ", "),
strsplit(y_val, split = ", "),
~paste(grep('([a-z])(?>\\d+)(?!\\1)', setdiff(.y, .x),
value = TRUE, perl = TRUE),
collapse = ", ")) %>%
replace(. == "", NA))
有人可以帮忙吗?
推荐答案
我在 https://stackoverflow.com/a/中修改了答案55285959/5150629 适合以下问题:
library(dplyr)
library(purrr)
df %>%
mutate(
diff_x = map2_chr(
strsplit(x_val, split = ","),
strsplit(y_val, split = ","),
~ {
setdiff(sub(":.+$", "", .x), sub(":.+$", "", .y)) %>%
grep('([a-z])(?>\\d+)(?!\\1)', ., value = TRUE, perl = TRUE) %>%
sapply(grep, .x, value = TRUE) %>%
paste(collapse = ", ") %>%
replace(. == "", NA)
}
),
diff_y = map2_chr(
strsplit(x_val, split = ","),
strsplit(y_val, split = ","),
~ {
setdiff(sub(":.+$", "", .y), sub(":.+$", "", .x)) %>%
grep('([a-z])(?>\\d+)(?!\\1)', ., value = TRUE, perl = TRUE) %>%
sapply(grep, .y, value = TRUE) %>%
paste(collapse = ", ") %>%
replace(. == "", NA)
}
)
)
输出:
x y x_val y_val diff_x
1 A B x2x:0.12345,y67h:0.06732,d7j:0.032647 x2y:0.33134,y67y:0.3131,d7r:0.23443 y67h:0.06732, d7j:0.032647
2 B C x2y:0.26345,y67y:0.28320,d7r:0.043647 x2y:0.34311,y67y:0.14142,d7r:0.31431 <NA>
3 C A x2y:0.23435,y67y:0.28310,d7r:0.043547 x2x:0.34314,y67h:0.14141,d7j:0.453145 x2y:0.23435, d7r:0.043547
4 C D x2y:0.23435,y67y:0.28330,d7r:0.043247 x67b:0.31411,g72v:0.3134,b8c:0.89234 x2y:0.23435, d7r:0.043247
diff_y
1 x2y:0.33134, d7r:0.23443
2 <NA>
3 y67h:0.14141, d7j:0.453145
4 x67b:0.31411, g72v:0.3134, b8c:0.89234
注意:
-
因为我们只想比较第一个字符串格式
x1y:000000
的一部分,我添加了sub(:。+ $,,.x)$ c每个
map2_chr
输入参数$ c>首先剥去:000000
部分。
Since we are only interested in comparing the first part of the string format
x1y:000000
, I added asub(":.+$", "", .x)
for eachmap2_chr
input argument to strip out the:000000
part first.
setdiff
和以下 grep
步骤可以正常工作以返回不匹配项,并排除格式为 x1x
的字符串。
setdiff
and the following grep
steps work as expected to return the mismatches and exclude strings with the form x1x
.
sapply(grep,.x,value = TRUE)
> grep 获取不匹配的向量,并搜索其对应的原始字符串(格式为 x1y:000000
)。
sapply(grep, .x, value = TRUE)
after the first grep
takes the vector of mismatches, and searches for their corresponding original strings (in x1y:000000
form).
粘贴
将不匹配的向量折叠成一个逗号分隔的列表。
paste
collapses the vector of mismatches into a single comma separated list.
这篇关于在特殊字符前匹配字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!