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

R语言中收入变量重编码仅首次运行有效,求问题排查

收入变量重编码问题排查与解决方案

问题说明

对参与者收入变量Q5进行重编码时出现以下问题:编写的重编码代码仅在刚写完时能正常运行,关闭R再重新打开后就失效,必须重新复制代码才能再次运行,团队成员均遇到相同情况。需排查原因并提供可用于论文的解决方案。

现有代码

BTW_2021 <- BTW_2021 %>% 
  mutate(Q5 = recode(Q5, "800â,¬" = "800",
                     "Verstehe die Frage nicht" = "-",
                     "4300â,¬" = "4300",
                     "2000â,¬" = "2000",
                     "Ca. 1000â,¬" = "1000",
                     "~1.700" = "1700",
                     "1700â,¬" = "1700",
                     "Nicht regelmäÃYig, nur sommerjob" = "-",
                     "Keine Angabe" = "-",
                     "Kein festes monatliches Einkommen" = "-",
                     "0â,¬" = "0",
                     "Keins, weil Schüler" = "0",
                     "1500-3000â,¬" = "1500",
                     "4500â,¬" = "4500",
                     "Mindestens 350â,¬" = "350",
                     "/" = "-",
                     "Nö" = "-",
                     "420â,¬ +Bafög" = "420",
                     "1.250" = "1250",
                     "1,500" = "1500",
                     "Keine Ahnung" = "-",
                     "1389,00" = "1389",
                     "450â,¬" = "450",
                     "Keins" = "0",
                     "250â,¬" = "250",
                     "k.A." = "0",
                     "3600 â,¬" = "3600",
                     "900â,¬" = "900",
                     "2400â,¬" = "2400",
                     "1.900â,¬" = "1900",
                     "0 (Schüler)" = "0",
                     "3750â,¬" = "3750",
                     "2.400 â,¬" = "2400",
                     "Bafög (860â,¬)" = "860",
                     "5.000" = "5000",
                     "4000 â,¬"  = "4000",
                     "0â,¬" = "0",
                     "300â,¬" = "300",
                     "2.300" = "2300",
                     "40â,¬" = "40",
                     "0 (da Student)" = "0"))

原始数据

BTW_2021 <- BTW_2021 %>% 
  select(Q5)
dput(BTW_2021)
structure(list(Q5 = c("Bitte geben Sie Ihr monatliches Haushaltsnettoeinkommen in Euro an.", 
"{\"ImportId\":\"QID6_TEXT\"}", "900", "800€", "Verstehe die Frage nicht ", 
"400", "6000", "4600", "3700", "800", "10000", "-", "1300", "2300", 
"0", "670", "2500", "0", "-", "8500", "2700 ", "2000", "1000", 
"1500", "180", "4300€", "0.00", "1300", "450", "4000", "1100", 
"8000", "3000", "2000€", "861", "5000", "1250 ", "2600", "6000", 
"450", "1400", "450", "4800", "4900", "-", "0", "500", "2500", 
"Ca. 1000€", "1", "2400", "2500", "1700", "0", "1700€", "750", 
"450", "3400", "1300", "13000", "1400", "1400", "Nicht regelmäßig, nur sommerjob", 
"800€", "2700", "150", "2100", "8000", "0", "12000", "600", 
"450", "4000", "1000", "1500-3000€", "0", "-", "-", "2000", 
"600", "-", "0€", "0", "2531", "800", "1200", "?", "500", "1100", 
"0", "2950", "4000", "4500€", "1500", "1800", "Mindestens 350€", 
"450", "8600", "7000", "-", "750", "0", "5000", "900", "4000", 
"-", "420€ +Bafög", "2000", "-", "6000", "800", "3500", "4000", 
"3000", "4500", "400", "450", "4000", "1600", "3300", "2500", 
"1500", "815", "2800", "3500", "100", "2500", "300", "500", "1749", 
"700", "1250", "450", "1200", "700", "426", "900", "0", "0", 
"1500", "0", "1250", "1700", "700", "-", "-", "200", "4000", 
"5500", "3200", "0", "600", "1389", "5000", "-", "900", "600", 
"3100", "2000", "850", "1535", "450€", "1400", "2500", "850", 
"0", "250€", "2700", "777", "700", "5500", "-", "2350", "6000", 
"219", "3000", "3000", "0 ", "1500", "1800", "-", "0", "1900", 
"1600", "2600", "3600 €", "900€", "1200", "1000", "2700", 
"5600", "650", "1200", "450", "15000", "800", "2600", "200", 
"2.400 €", "2300", "2400", "-", "600", "0", "0", "1.900€", 
"1300", "450", "800", "800", "2000", "0", "Keine Ahnung ", "2500", 
"200", "3500", "500", "1600", "20000", "0", "-", "3750€", "2400€", 
"2800", "10000", "700", "4500", "1100", "1200", "Bafög (860€)", 
"8000", "3500", "860", "1000", "1800", "5000", "1000", "600", 
"950", "0", "3000", "4000 €", "0€", "2400", "1600", "1500", 
"900", "300€", "2500", "2300", "1700", "4500", "40€", "250", 
"0", "450", "0", "600", "2800", "1200", "1600")), row.names = c(NA, 
-261L), class = "data.frame")

问题原因

  • 字符编码与匹配项不匹配:代码中的特殊字符(如â,¬)和实际数据中的€(欧元符号乱码后)不一致;部分匹配项存在空格差异(比如数据中是Verstehe die Frage nicht 带空格,代码中无空格),导致重启R后字符编码加载变化,匹配失效。
  • 未固化处理流程:未将代码保存为脚本文件,也未保存处理后的数据,每次重启R都需重新执行代码才能生效。
  • recode函数局限性:recode需完全匹配字符串,一旦字符编码或空格有细微差异就会匹配失败,容错性低。

解决方案

1. 修正编码与匹配逻辑,用正则简化处理

替换原recode代码,使用case_when结合正则表达式,提升匹配容错性,同时统一处理特殊字符:

library(dplyr)
library(stringr)

# 先清理无效的初始行(如问题提示、ImportId)
BTW_2021 <- BTW_2021 %>%
  filter(!str_detect(Q5, "Bitte geben Sie Ihr monatliches|ImportId")) %>%
  mutate(Q5 = case_when(
    # 提取所有含数字的内容,去除欧元符号、千分位分隔符、空格
    str_detect(Q5, "\\d") ~ str_replace_all(Q5, "[€.,\\s]", ""),
    # 标记所有无效回答为"-"
    str_detect(Q5, "Verstehe die Frage nicht|Nicht regelmäßig, nur sommerjob|Keine Angabe|Kein festes monatliches Einkommen|Keine Ahnung|/|Nö|k\\.A\\.|\\?") ~ "-",
    # 标记无收入/学生情况为"0"
    str_detect(Q5, "Keins, weil Schüler|Keins|0 \\(Schüler\\)|0 \\(da Student\\)|0 ") ~ "0",
    # 保留已正确的标记
    Q5 %in% c("-", "0") ~ Q5,
    # 其他未匹配项默认标记为"-"
    TRUE ~ "-"
  ))

2. 固化处理流程与数据

  • 将上述代码保存为独立的R脚本(如recode_Q5.R),每次打开R后直接运行脚本,无需重复复制。
  • 处理完成后保存数据,避免重复处理:
    # 保存为RData格式,保留数据结构
    save(BTW_2021, file = "BTW_2021_recode.RData")
    # 或保存为CSV,方便跨工具查看
    write.csv(BTW_2021, file = "BTW_2021_recode.csv", row.names = FALSE)
    
  • 下次打开R时,直接加载处理好的数据:
    load("BTW_2021_recode.RData")
    

3. 验证结果

执行代码后,用以下命令检查重编码结果:

table(BTW_2021$Q5)

确认所有无效回答都被标记为-,有效数字均被正确提取。

内容的提问来源于stack exchange,提问作者Mr. Draro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 13:24:53