我在匹配r中的多个字符串时遇到困难。我拥有的数据框如下所示:
Var1 Var2
1 SJDJWK P04TGI7F3;P030Y7Y11;PE35RV747;Q2UKLVVX4
2 ODJSMDK Q2UKLVVX4;PWER00711;PE35RV747;Q2UKLVVX4
3 JDKSAKDJ PE35RV747;P0F071G1G
我想匹配用“;”分隔的字符串具有以下数据框中的值:
Var_x Var_y
1 P04TGI7F3 good
2 P030Y7Y11 normal
3 PE35RV747 bad
4 Q2UKLVVX4 normal
这样生成的数据框看起来像:
Var1 Var2 Var3
1 SJDJWK P04TGI7F3;P030Y7Y11;PE35RV747;Q2UKLVVX4 good;normal;bad;normal
2 ODJSMDK Q2UKLVVX4;PWER00711;PE35RV747;Q2UKLVVX4 normal;bad;normal
3 JDKSAKDJ PE35RV747;P0F071G1G bad
到目前为止,我尝试通过模糊连接来实现:
fuzzy_left_join(Data1, Data2, by = c("Var2"="Var_x"), match_fun = str_detect)
这可以完成工作,但是它占用了大量内存(我的数据集非常大,R停止工作)。我试图通过for循环来做到这一点,但是我不知道该怎么做。有人知道吗?
答案 0 :(得分:2)
使用基数R,遍历Var2,在";"
上分割,然后进行 match :
df1$Var3 <- sapply(df1$Var2, function(i){
paste(df2$Var_y[ match(unlist(strsplit(i, split = ";")), df2$Var_x) ], collapse = ";")
})
# Var1 Var2 Var3
# 1 SJDJWK P04TGI7F3;P030Y7Y11;PE35RV747;Q2UKLVVX4 good;normal;bad;normal
# 2 ODJSMDK Q2UKLVVX4;PWER00711;PE35RV747;Q2UKLVVX4 normal;NA;bad;normal
# 3 JDKSAKDJ PE35RV747;P0F071G1G bad;NA
注意:我知道我的输出在Var3中具有NA,而OP的预期输出却没有。但是我更喜欢保留NA,以便我们可以按原始字符串中的位置将每个“坏/正常”匹配到对应的字符串。当然,如果OP愿意,可以使用na.omit
将其删除:
df1$Var3 <- sapply(df1$Var2, function(i){
paste(na.omit(df2$Var_y[ match(unlist(strsplit(i, split = ";")), df2$Var_x) ]), collapse = ";")
})
# Var1 Var2 Var3
# 1 SJDJWK P04TGI7F3;P030Y7Y11;PE35RV747;Q2UKLVVX4 good;normal;bad;normal
# 2 ODJSMDK Q2UKLVVX4;PWER00711;PE35RV747;Q2UKLVVX4 normal;bad;normal
# 3 JDKSAKDJ PE35RV747;P0F071G1G bad
答案 1 :(得分:2)
这是一个通过tidyverse
的想法。我们分离行,在第二个数据帧上合并,然后再次基于Var1
进行连接,
library(tidyverse)
df1 %>%
separate_rows(Var2) %>%
left_join(df2, by = c('Var2' = 'Var_x')) %>%
group_by(Var1) %>%
summarise_all(funs(paste(., collapse = ';')))
给出,
# A tibble: 3 x 3 Var1 Var2 Var_y <fct> <chr> <chr> 1 JDKSAKDJ PE35RV747;P0F071G1G bad;NA 2 ODJSMDK Q2UKLVVX4;PWER00711;PE35RV747;Q2UKLVVX4 normal;NA;bad;normal 3 SJDJWK P04TGI7F3;P030Y7Y11;PE35RV747;Q2UKLVVX4 good;normal;bad;normal
如果您不想包含NAs
,我们可以在加入之前省略(如@akrun所述),即
df1 %>%
separate_rows(Var2) %>%
filter(Var2 %in% df2$Var_x) %>%
left_join(df2, by = c('Var2' = 'Var_x')) %>%
group_by(Var1) %>%
summarise_all(funs(paste(., collapse = ';')))
给出,
# A tibble: 3 x 3 Var1 Var2 Var_y <fct> <chr> <chr> 1 JDKSAKDJ PE35RV747 bad 2 ODJSMDK Q2UKLVVX4;PE35RV747;Q2UKLVVX4 normal;bad;normal 3 SJDJWK P04TGI7F3;P030Y7Y11;PE35RV747;Q2UKLVVX4 good;normal;bad;normal
答案 2 :(得分:2)
玩data.table
df2[df1[, unlist(tstrsplit(Var2, ";")), Var1],
on = .(Var_x = V1)
][,
lapply(.SD, function(x) paste(x[!is.na(x)], collapse = ";")),
by = Var1
]
Var1 Var_x Var_y
1: SJDJWK P04TGI7F3;P030Y7Y11;PE35RV747;Q2UKLVVX4 good;normal;bad;normal
2: ODJSMDK Q2UKLVVX4;PWER00711;PE35RV747;Q2UKLVVX4 normal;bad;normal
3: JDKSAKDJ PE35RV747;P0F071G1G bad
答案 3 :(得分:2)
另一个带有gsubfn
的选项,其中我们为list
个字符中的replacement
中的gsubfn
中的{{1} pattern
。请注意,在某些情况下,
'df2'。如果所有替换项都在那里,则不需要第二个;
(假设在示例中未提供)
gsub
library(gsubfn)
df1$Var_y <- gsub(";[A-Z0-9]+", "", gsubfn("[^;]+",
setNames(as.list(df2$Var_y), df2$Var_x), df1$Var2))
df1
# Var1 Var2 Var_y
#1 SJDJWK P04TGI7F3;P030Y7Y11;PE35RV747;Q2UKLVVX4 good;normal;bad;normal
#2 ODJSMDK Q2UKLVVX4;PWER00711;PE35RV747;Q2UKLVVX4 normal;bad;normal
#3 JDKSAKDJ PE35RV747;P0F071G1G bad
答案 4 :(得分:0)
您可以在基本folder1/file1
folder2/file2
中从第二个R
构建一个命名向量,然后在拆分之后,我们在该命名向量中查找所有相关值,删除NA并粘贴回去。
data.frame