R dplyr(),full join 两个data,一个exact match, 一个fuzzy match

img


我有两个data,我想通过它们都有的两个columns full join它们, 一个column叫c_id,一个column叫c_name,我想用c_id full join的时候exact match, 用c_name full join的时候95% fuzzy match。 于是我写了图片上的代码,可是我不太懂出现的错误是什么意思,有没有同学可以帮忙看看捏🥲

看看你的which参数是什么?

你遇到的错误信息表明传递给'which'函数的参数不是逻辑型的,意味着它的格式或类型不正确。请确保传递给'which'函数的参数是逻辑型的,可以使用逻辑运算符或逻辑函数来获取逻辑值,例如TRUE或FALSE。

引入ChatGPT部分内容参考作答:
这个错误是因为在使用fuzzy_full_join函数时,match_fun参数需要传递一个函数列表,其中每个函数都需要是一个函数对象。在你的代码中,stringdist::stringdist是一个函数对象,但是'=='是一个运算符,不是一个函数对象。因此,你需要将'=='替换为一个函数对象,例如base::identical。另外,你需要将distance_col参数改为distance_col_name,因为fuzzy_full_join函数中没有distance_col参数。下面是修改后的代码:

View(br_code_master_test2)
br_code_master_test2 <- fuzzy_full_join(br_code_master,data.temp.br,
                         by = c("c_id","c_name"),
                         match_fun=list(base::identical,stringdist::stringdist), 
                         distance_col_name="name_distance")

以下答案由GPT-4.5Plus大模型(语音)与博主A努力中.......共同编写:

出现错误的原因是:

  1. 在进行fuzzy join时,c_name列为字符串类型,而使用的距离度量方式是欧几里德距离(euclidean),这是针对数值型特征的距离计算方法,不适用于字符串。
  2. 您试图在pandas里面直接执行fuzzy join,但pandas不支持fuzzy join,只支持传统的SQL join(inner join、left join等)。

要解决这个问题,可以:

  1. 对c_name列进行向量化,比如使用sklearn的TfidfVectorizer将字符串转为 tfidf 向量,然后基于 tfidf 向量计算相似度。

  2. 不要直接使用pandas的join方法,而是:
    (1) 使用sklearn的NearestNeighbors在c_name的tfidf向量上构建近邻搜索结构。
    (2) 对每一行记录,在NearstNeighbors中搜索与其c_name最相似的k条记录(k可以设置为1)。
    (3) 如果搜索出的记录与当前记录的c_id也相同,则认为是exact match;如果c_id不同但相似度超过阈值(如95%),则认为是fuzzy match。
    (4) 根据match的结果构建新的DataFrame,并使用pandas的concat方法将两个原DataFrame按exact match和fuzzy match的结果连接起来。

修正后的代码可以如下:

python
from sklearn.feature_extraction.text import TfidfVectorizer 
from sklearn.neighbors import NearestNeighbors

# 将c_name进行TfidfVectorizer向量化    
tfidf = TfidfVectorizer()
text_data1 = tfidf.fit_transform(data1['c_name'])
text_data2 = tfidf.transform(data2['c_name'])

# 构建NearestNeighbors模型
nn = NearestNeighbors(n_neighbors=1)  
nn.fit(text_data2)

# 查找每个data1中c_name的最近邻,判断是否match
exact_match = [] 
fuzzy_match = []
for idx, row in data1.iterrows():
    c_id1 = row['c_id']
    c_name1 = row['c_name']
    
    # 搜索最近的1个邻居
    nearest_ix = nn.kneighbors([text_data1[idx]], n_neighbors=1)  
    
    # 如果c_id也相等,则exact match
    if data2.loc[nearest_ix[1][0][0], 'c_id'] == c_id1:
        exact_match.append(row)
    # 否则检查相似度,如果超过95%则fuzzy match
    elif nn.kneighbors([text_data1[idx]], n_neighbors=1)[0][0][0] > 0.95: 
        fuzzy_match.append(row)
        
# 将两个DataFrame concat起来  

result = pd.concat([pd.DataFrame(exact_match), pd.DataFrame(fuzzy_match)], axis=0) 

可以参考下

R语言使用dplyr包进行多个dataframe的全连接(full join)
​
data3 <- data.frame(ID = c(2, 4),                   
# Create third example data frame
                    X2 = c("c1", "c2"),
                    X3 = c("d1", "d2"),
                    stringsAsFactors = FALSE)
data3                                               

# Print data to RStudio console
# ID X2 X3
#  2 c1 d1
#  4 c2 d2

full_join(data1, data2, by = "ID") %>%              
# Full outer join of multiple data frames
  full_join(., data3, by = "ID") 
# ID   X1 X2.x X2.y   X3
#  1   a1 <NA> <NA> <NA>
#  2   a2   b1   c1   d1
#  3 <NA>   b2 <NA> <NA>
#  4 <NA> <NA>   c2   d2


R语言使用dplyr包的full_join函数基于多个字段(数据列)全连接两个dataframe、按照多列对数据进行全连接
可以参考下
https://blog.csdn.net/weixin_57242009/article/details/125091531