使用left_join合并数据时仅得到NA值的问题求助
问题:left_join合并.sav数据后附加列全为NA
问题背景
我有两份封闭式问卷导出的.sav格式数据:
- 一份是2800行的受访者ID列表(
resp数据集) - 另一份是8500行的包含所有ID及附加信息的列表(
panelleden数据集)
目标是通过left_join合并,得到仅包含受访者ID对应信息的2800行数据。
基础示例验证
基础测试中left_join运行正常:
quest <- data.frame( a = c(1:10), b = c("abc", "def", "ghi", "jkl", "mno", "pqr", "stu", "vwx", "yzA", "BCD"), c = c(23,65,87,32,45,67,87,34,110,12)) resp <- data.frame( a = c(1,3,8,6,2,5)) left_join(resp, quest, by = "a")
运行结果:
a b c 1 1 abc 23 2 3 ghi 87 3 8 vwx 34 4 6 pqr 67 5 2 def 65 6 5 mno 45
实际问题复现
但处理真实数据时,合并后所有附加列均为NA:
> head(panelleden,2) # A tibble: 2 × 8 corop coropNaam geslacht opleiding leeftijd_jaren respondent lijst_id panel_resp_id_b <chr> <chr> <dbl+lbl> <dbl+lbl> <dbl> <dbl> <chr> <chr> 1 CR05 Zuidwest-Friesland 2 [Vrouw] 2 [Midden] 54 10609 lijstintake ba28a5c372ca9bbb20d3613e65e0bc47 2 CR04 Noord-Friesland 1 [Man] 1 [Laag] 45 31409 lijstintake 0eff6e236090beeece4ecb5de0cc773c > head(resp,2) # A tibble: 2 × 1 panel_resp_id_b <chr> 1 de25f0b0942ebc63172e9b2fcc265de3 2 8ee2915d22a22e6130bed90cdb3d3379 > left_join(resp, panelleden, by = "panel_resp_id_b") # A tibble: 2,802 × 8 panel_resp_id_b corop coropNaam geslacht opleiding leeftijd_jaren respondent lijst_id <chr> <chr> <chr> <dbl+lbl> <dbl+lbl> <dbl> <dbl> <chr> 1 de25f0b0942ebc63172e9b2fcc265de3 NA NA NA NA NA NA NA 2 8ee2915d22a22e6130bed90cdb3d3379 NA NA NA NA NA NA NA
已尝试的操作:
- 使用
trimws()处理ID列的空格 - 指定
join_by()参数 - 检查两个数据集的ID列均无NA值
但问题仍未解决。
解决方案建议
1. 排查不可见字符
.sav文件导入后,字符串可能包含肉眼无法识别的不可见字符(如换行符、制表符、全角空格等),导致匹配失败。可以通过以下代码排查:
# 查看ID的字符长度 nchar(resp$panel_resp_id_b[1]) nchar(panelleden$panel_resp_id_b[1]) # 打印原始字符的字节码,对比是否一致 charToRaw(resp$panel_resp_id_b[1]) charToRaw(panelleden$panel_resp_id_b[1])
如果长度或字节码不一致,用gsub()清除非打印字符:
# 清除所有非打印ASCII字符 resp$panel_resp_id_b <- gsub("[[:cntrl:]]", "", resp$panel_resp_id_b) panelleden$panel_resp_id_b <- gsub("[[:cntrl:]]", "", panelleden$panel_resp_id_b) # 重新尝试合并 left_join(resp, panelleden, by = "panel_resp_id_b")
2. 统一ID列的数据类型
确认两个ID列都是字符型:
class(resp$panel_resp_id_b) class(panelleden$panel_resp_id_b)
如果其中一个是因子型,先转换为字符型:
resp$panel_resp_id_b <- as.character(resp$panel_resp_id_b) panelleden$panel_resp_id_b <- as.character(panelleden$panel_resp_id_b)
3. 验证ID是否存在重叠
用intersect()确认两个数据集是否有匹配的ID:
intersect(resp$panel_resp_id_b, panelleden$panel_resp_id_b)
如果结果为空,说明两份数据的ID完全不匹配,需要检查数据来源是否一致(如是否为同一批次问卷、ID是否被修改)。
4. 用stringi包深度清理字符串
如果以上方法无效,尝试用stringi包的函数彻底标准化字符串:
library(stringi) resp$panel_resp_id_b <- stri_trim_both(stri_trans_general(resp$panel_resp_id_b, "any-ascii")) panelleden$panel_resp_id_b <- stri_trim_both(stri_trans_general(panelleden$panel_resp_id_b, "any-ascii"))
内容的提问来源于stack exchange,提问作者Myrthe Kroes
相关产品推荐
相关产品推荐

