好的,所以我不久前发布了一个关于编写R函数以加速大文本文件串匹配的问题。我把眼睛打开了'data.table',我的问题得到了很好的回答。
这是指向该主题的链接,其中包含所有数据和详细信息:
Accelerate performance and speed of string match in R
但现在我遇到了另一个问题。偶尔,提交的VIN#s(在'vinDB'文件中)在'carFile'文件中由于人为错误而在DMV上填写他们的汽车信息时相差一两个字符。有没有办法编辑
dt[J(car.vins), list(NumTimesFound=.N), by=vin.names]
该代码的行(由@BrodieG在上面的链接中提供)允许识别相差一个或两个字符的VIN#?
如果这是一个简单的修正,我道歉。我只是被R中'data.table'软件包的力量所震撼,并希望尽可能多地学习它的实用性,而且这个论坛的知识渊博的成员对我来说绝对是关键。
**编辑:
所以我一直在玩'lapply'和'agrep'功能,我必须做错事:
我尝试更换此行:
dt[J(car.vins), list(NumTimesFound=.N), by=vin.names]
用这个:
dt <- dt[lapply(vin.vins, function(x) agrep(x,car.vins, max.distance=2)), list(NumTimesFound=.N), vin.names, allow.cartesian=TRUE]
但是出现了以下错误:
Error in `[.data.table`(dt, lapply(vin.vins, function(x) agrep(x,car.vins, :
x.'vin.vins' is a character column being joined to i.'V1' which is type 'integer'.
Character columns must join to factor or character columns.
但他们都是'chr'型。有谁知道我为什么会收到这个错误?我是否正确地思考这个问题,即:我在这里正确使用lapply吗?
谢谢!
答案 0 :(得分:4)
我终于明白了。
'agrep'函数有一个'value'选项需要从FALSE(默认)更改为true:
>dt <- dt[lapply(car.vins, agrep, x=vin.vins, max.distance=c(cost=2, all=2), value=TRUE), list(NumTimesFound=.N), vin.names]
注意:max.distance参数可以根据Levenshtein距离,替换,删除等进行更改.'agrep'是一个非常有趣的功能!
再次感谢您的帮助!
答案 1 :(得分:0)
感谢您对部分匹配问题的回答。这是我在自己的机器上工作的完整代码(包括BrodieG在您的链接帖子中提供的可重现的示例)。我必须将lapply
更改为sapply
。
library(data.table)
set.seed(1)
makes <- c("Toyota", "Ford", "GM", "Chrysler")
years <- 1995:2014
cars <- paste(sample(makes, 500, rep=T), sample(years, 500, rep=T))
vins <- unlist(replicate(500, paste0(sample(LETTERS, 16), collapse="")))
vinDB <- data.frame(c(cars, vins)[order(rep(1:500, 2))])
carFile <- data.frame(c(rep("junk", 1000), sample(vins, 1000, rep=T), rep("junk", 2000))[order(rep(1:1000, 4))])
vin.names <- vinDB[seq(1, nrow(vinDB), 2), ]
vin.vins <- vinDB[seq(2, nrow(vinDB), 2), ]
car.vins <- carFile[seq(2, nrow(carFile), 4), ]`
#Add some errors to car.vins strings
s <- sample(length(car.vins),100)
car.vins.err <- as.character(car.vins)
car.vins.err[s] <- gsub("A","B",car.vins.err[s])
s <- sample(length(car.vins.err),100)
car.vins.err[s] <- gsub("E","F",car.vins.err[s])
s <- sample(length(car.vins.err),100)
car.vins.err[s] <- gsub("I","J",car.vins.err[s])
car.vins.err <- as.factor(car.vins.err)`
dt <- data.table(vin.names, vin.vins, key="vin.vins")
dt1 <- dt[J(car.vins), list(NumTimesFound=.N), keyby=vin.names]
dt1.err <- dt[J(car.vins.err), list(NumTimesFound=.N), keyby=vin.names]
dt2 <- dt[sapply(car.vins, agrep, x=vin.vins, max.distance=c(cost=2, all=2), value=TRUE), list(NumTimesFound=.N), keyby=vin.names]
dt2.err <- dt[sapply(car.vins.err, agrep, x=vin.vins, max.distance=c(cost=2, all=2), value=TRUE), list(NumTimesFound=.N), keyby="vin.names"]
dt1[dt1.err][dt2.err]