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
相关产品推荐
相关产品推荐

