使用R,我试图在一个按年和城市结构的数据集中匹配人们的名字。由于一些拼写错误,精确匹配是不可能的,所以我试图使用grep()来模糊匹配名称。
数据集的样本块的结构如下所示:
df <- data.frame(matrix( c("1200013","1200013","1200013","1200013","1200013","1200013","1200013","1200013", "1996","1996","1996","1996","2000","2000","2004","2004","AGUSTINHO FORTUNATO FILHO","ANTONIO PEREIRA NETO","FERNANDO JOSE DA COSTA","PAULO CEZAR FERREIRA DE ARAUJO","PAULO CESAR FERREIRA DE ARAUJO","SEBASTIAO BOCALOM RODRIGUES","JOAO DE ALMEIDA","PAULO CESAR FERREIRA DE ARAUJO"), ncol=3,dimnames=list(seq(1:8),c("citycode","year","candidate")) ))
整洁的版本:
citycode year candidate
1 1200013 1996 AGUSTINHO FORTUNATO FILHO
2 1200013 1996 ANTONIO PEREIRA NETO
3 1200013 1996 FERNANDO JOSE DA COSTA
4 1200013 1996 PAULO CEZAR FERREIRA DE ARAUJO
5 1200013 2000 PAULO CESAR FERREIRA DE ARAUJO
6 1200013 2000 SEBASTIAO BOCALOM RODRIGUES
7 1200013 2004 JOAO DE ALMEIDA
8 1200013 2004 PAULO CESAR FERREIRA DE ARAUJO
我想分别在每个城市登记,几年后是否有候选人出现。例如,在示例中,
PAULO CEZAR FERREIRA DE ARAUJO
保罗·塞萨尔·费雷拉·德阿劳乔
出现两次(拼写错误)。整个数据集中的每个候选者都应该被分配一个唯一的数字候选ID。数据集相当大(约5500个城市。100K条目),所以一个有点有效的编码将是有帮助的。关于如何实施这一点,有什么建议吗?
编辑:以下是我的尝试(在目前评论的帮助下),它在完成手头的任务方面非常缓慢(低效)。对此有何改进建议?
f <- function(x) {matches <- lapply(levels(x), agrep, x=levels(x),fixed=TRUE, value=FALSE)
levels(x) <- levels(x)[unlist(lapply(matches, function(x) x[1]))]
x
}
temp <- tapply(df$candidate, df$citycode, f, simplify=TRUE)
df$candidatenew <- unlist(temp)
df$spellerror <- ifelse(as.character(df$candidate)==as.character(df$candidatenew), 0, 1)
编辑2:现在以良好的速度运行。问题是每一步都要与许多因素进行比较(谢谢你指出这一点,蓝先生)。将比较减少到一组(即一个城市)中的候选人,在5秒钟内运行80,000行命令——这是我可以忍受的速度。
df$candidate <- as.character(df$candidate)
f <- function(x) {x <- as.factor(x)
matches <- lapply(levels(x), agrep, x=levels(x),fixed=TRUE, value=FALSE)
levels(x) <- levels(x)[unlist(lapply(matches, function(x) x[1]))]
as.character(x)
}
temp <- tapply(df$candidate, df$citycode, f, simplify=TRUE)
df$candidatenew <- unlist(temp)
df$spellerror <- ifelse(as.character(df$candidate)==as.character(df$candidatenew), 0, 1)
好的,鉴于重点是效率,我建议如下。
首先,请注意,根据第一原理的效率顺序,我们可以预测精确匹配将比grep快得多,grep将比模糊grep快得多。所以精确匹配,然后对剩余的观测值进行模糊grep。
第二,矢量化和避免循环。apply
命令并不一定更快,因此如果可以,请坚持使用本机矢量化。所有的grep
命令都是本机矢量化的,但是很难避免使用*ply
或循环将每个元素与其他元素的矢量进行比较。
第三,利用外部信息缩小问题范围。只对每个城市或州的名字进行模糊匹配,这将大大减少必须进行的比较次数。
您可以结合第一和第三个原则:您甚至可以尝试对每个字符串的第一个字符进行精确匹配,然后在其中进行模糊匹配。
这是我的机会。这可能不是很有效,但我认为它会完成这项工作。我假设df$候选人
是类因素。
#fuzzy matches candidate names to other candidate names
#compares each pair of names only once
##by looking at names that have a greater index
matches <- unlist(lapply(1:(length(levels(df[["candidate"]]))-1),
function(x) {max(x,x + agrep(
pattern=levels(df[["candidate"]])[x],
x=levels(df[["candidate"]])[-seq_len(x)]
))}
))
#assigns new levels (omits the last level because that doesn't change)
levels(df[["candidate"]])[-length(levels(df[["candidate"]]))] <-
levels(df[["candidate"]])[matches]
问题内容: 我有两个dataframes(X,Y),其中ID是,和。由于存在印刷错误(“ n”而不是“ m”,随机的空格等),尽管我可以查看数据并看到应有的值,但我仍有大约60%的值未对齐。有没有办法以某种方式减少不匹配的程度,以便至少可以进行手动编辑?数据帧具有约700K观测值。 R最好。我知道一些python和一些基本的unix工具。PS我继续阅读,但不了解如何将其应用于实际数据集,尤其是当匹
问题内容: 所以我创建了这两个类 现在这是两者的简化版本,但足以说明我的问题。此处显示的类将无法使用,因为找不到四分之一类。为了使其工作,我可以将$ class变量更改为 所以我的问题是:当两个类已经是同一个命名空间的成员时,为什么需要在这里使用命名空间。仅当我将类名放入变量中时,才需要名称空间: 可以正常工作。为什么会这样?在这里有什么需要避免的潜在陷阱吗? 问题答案: 因为可以将字符串从一个名
问题内容: 我想对Elasticsearch的电子邮件或电话进行模糊匹配。例如: 匹配所有以结尾的电子邮件 要么 匹配所有电话开头。 我知道我可以使用通配符 但是性能很差。我尝试使用regexp: 但是不起作用。 有更好的方法吗? curl -XGET本地主机:9200 / user_data 映射: 问题答案: 一种简单的方法是创建一个自定义分析器,该分析器使用电子邮件的n-gram令牌过滤器(
问题内容: 我正在使用Jenkins Pipeline插件,并且需要从其他作业中通过其ID和作业名称获取特定版本的所有参数。所以,基本上我需要这样的东西。 问题答案: 我想到了。我可以像这样检索参数
在Symfony 4中是否可以通过yaml设置路由名称。 如此古老的诠释 Yaml注释 看起来yaml不支持名称键。只支持以下键: “资源”、“类型”、“前缀”、“路径”、“主机”、“方案”、“方法”、“默认值”、“要求”、“选项”、“条件”、“控制器”。 或者密钥“login”是名称吗?
问题内容: 如果我在字符串中有一个对象和一个方法名称,该如何调用该方法? 问题答案: 使用内置功能: 您还可以用于通过名称设置类属性。
我正在使用 YouTube 合作伙伴 API 代表合作伙伴上传视频,以便跟踪和报告获利情况。过程如下:用户将视频上传到网站。将视频推送到合作伙伴拥有的频道,创建资产,为上传到合作伙伴频道的视频创建版权主张。视频被推送到用户的公共YouTube频道 所有这些都是有效的,但我无法弄清楚如何设置“启用内容ID匹配”选项,该选项位于YouTube CMS视频部分。需要启用此功能,以便匹配上传到用户公共频道