我对诸如在R中查找和匹配多个字符串的功能有疑问。
我在下面有3张桌子。
表1:根据辖区,产品代码和费率,产品代码可以分为两个部分,主要的是前3个产品代码,后两个是次要代码,例如AB010,AB020,AB030是主代码,AB040,AB050是辅助键。
表2:具有司法管辖区和产品名称,产品名称将在主要代码和次要代码之间包含许多无意义的字符串,但是它将始终仅包含一个主要代码,并且可能包含或可能不包含次要代码并以“ _”分隔
表3:输出表,我想从表2的产品名称中搜索并返回产品代码,并匹配表1中的费率,例如 如果产品名称同时包含AB010和AB040,则为1.1 + 1.4 = 2.5。
我目前在R中使用了很多嵌套的ifelse函数。
final String answer = faq['answer'];
答案 0 :(得分:0)
这是fuzzyjoin
软件包的绝佳用例;您可以将Table1
中的代码视为正则表达式,并将其与Table2
中的较长字符串进行匹配。尝试如下操作:
library(dplyr)
library(fuzzyjoin)
table3 = Table2 %>%
regex_left_join(Table1 %>%
mutate(product.regex = paste("(_|^)", Product.Code, "(_|$)", sep = ""),
jurisdiction.regex = paste("^", Jurisdiction, "$", sep = "")),
by = c("Product.name" = "product.regex",
"Jurisdiction_2" = "jurisdiction.regex")) %>%
group_by(Jurisdiction_2, Product.name) %>%
summarize(Product.Codes = toString(Product.Code),
Rate = sum(Rates))
几点:
Product.Code
中的Table1
包裹在更长的正则表达式中,以确保在Table2
之前和之后都以_
或字符串结尾。如果您确定所有产品代码都是5个字符(即,任何产品代码都不是其他任何代码的子字符串),则没有必要。^...$
以强制管辖权完全匹配。如果您不需要在管辖权上进行匹配,则可以省略该部分。答案 1 :(得分:0)
这是使用sapply
Table3 <- as.data.frame(row.names = F,
t(
sapply(Table2$Product.name, function(pname) { # line 1
qry.names <- paste0("^", gsub("_", "|^", pname)) # line 2
pcodes <- grep(qry.names, Table1$Product.Code, perl = T) # line 3
pcodes.c <- paste0(sort(unique(Table1$Product.Code[pcodes])), collapse = "/") # line 4
Jurisdiction <- Table2$Jurisdiction_2[pname == Table2$Product.name] #line 5
list(Jurisdiction, pname, pcodes.c, sum(Table1$Rates[pcodes])) # line 6
})
)
)
# set column names
colnames(Table3) <- c("Jurisdiction", "Product name", "Product Code", "Rate")
> Table3
Jurisdiction Product name Product Code Rate
1 A 1234_AB010_dsf AB010 1.1
2 A 1234_AB010_AB040_tsdfl AB010/AB040 2.5
3 C 1238_ZH123_ZH131 ZH123/ZH131 2.6
4 B 123_X140 X140 1.3
function(pname)
中的每个Product.name
应用Table2
_
替换为|^
,并在前面附加一个附加的Product.name
,以将其用作在{{1}中搜索^
的查询} grep
匹配的Table1$Product.code
中Product.Code
的位置Table1
隔开的相应Table2$Product.name
Table1$Product.Code