You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 01:45:19