这是我的例子:
id <- 1:5
names_1 <- c("hannah", "marcus", "fred", "joe", "lara")
df_1 <- data.frame(id, names_1)
df_1$phonenumberFound <- NA
names_2 <- c("hannah", "markus", "fredd", "joey", "paul", "mary", "olivia")
phone <- c(123, 234, 345, 456, 567, 678, 789)
df_2 <- data.frame(names_2, phone)
我想要实现的是:
如果df_2中的一个名称(至少近似)与df_1中的名称匹配,那么我想在df_1中添加相应的电话号码。
基本上,这是一种模糊的左联接,但我没有成功完成。
实际上,我的真实df_1有30.000行,而我的真实df_2有500.000行。有快速的方法吗?
谢谢!
编辑:
在使用当前提供的答案遇到内存问题时,我需要更改和阐明示例。 (我正在使用具有16 GB RAM的Windows笔记本。)
id_1 <- 1:30000
names_1 <- sample(c("hannah", "marcus", "fred", "joe", "lara"), 30000, replace = TRUE, prob = c(0.2, 0.2, 0.2, 0.2, 0.2))
df_1 <- data.frame(id_1, names_1)
df_1$numberFound <- NA
id_2 <- 1:500000
names_2 <- sample(c("hannah", "markus", "paul", "mary", "olivia"), 500000, replace = TRUE, prob = c(0.2, 0.2, 0.2, 0.2, 0.2))
anyNumber <- sample(c(123, 234, 345, 456, 567), 500000, replace = TRUE, prob = c(0.2, 0.2, 0.2, 0.2, 0.2))
df_2 <- data.frame(id_2, names_2, anyNumber)
任何有用的评论和答案都将受到高度赞赏。
答案 0 :(得分:3)
这是fuzzyjoin
library(fuzzyjoin)
stringdist_right_join((df_2, df_1, by = c("names_2" = "names_1")) %>%
select(names(df_1), phone)
# id names_1 phone
#1 1 hannah 123
#2 2 marcus 234
#3 3 fred 345
#4 4 joe 456
#5 5 lara 678
或使用stringdistmatrix
包中的stringdist
创建矩阵
library(stringdist)
df_2$phone[max.col(-stringdistmatrix(df_1$names_1, df_2$names_2), 'first')]
答案 1 :(得分:3)
我们可以使用adist
来计算字符向量之间的字符串距离。
adist(df_1$names_1, df_2$names_2)
# [,1] [,2] [,3] [,4] [,5] [,6] [,7]
#[1,] 0 5 6 6 5 5 6
#[2,] 5 1 5 6 4 3 6
#[3,] 6 5 1 3 4 4 6
#[4,] 6 6 4 1 4 4 6
#[5,] 4 4 5 4 3 2 4
定义一些可以允许的合适阈值,并分配相应的phone
列。
thresh <- 1
mat <- adist(df_1$names_1, df_2$names_2) <= thresh
inds <- max.col(mat) * (rowSums(mat) > 0)
df_1$phone <- df_2$phone[replace(inds, inds == 0, NA)]
df_1
# id names_1 phone
#1 1 hannah 123
#2 2 marcus 234
#3 3 fred 345
#4 4 joe 456
#5 5 lara NA
但是,由于这会生成m
×n
矩阵,因此它可能不是最有效的方法。