使用dplyr对SQLite数据库表列值重编码报错如何解决?
错误原因
- 第一个报错根源:你在
recode()的第一个参数传入了整个bd(SQLite连接的懒查询表对象),面向本地向量设计的dplyr::recode语法要求第一个参数为待处理的单列,而适配SQL端计算的dbplyr无法将整个表对象转译为合法SQL语法,最终触发escape方法报错。 - 第二个警告根源:SQLite没有原生适配R风格
recode的命名传参逻辑,你使用的'1' = "xxx"命名式重赋值写法、以及.default = NULL参数,都无法被dbplyr正确转译为SQL语句,因此触发参数忽略警告。 - 隐性问题:你表中
f.19.0.0是数值类型(<dbl>),但你重编码的键用了字符型的'1',类型不匹配也会导致重编码失效。
解决方案
推荐使用兼容性更强的case_when()替代recode(),dbplyr对case_when的SQL转译支持更成熟,完全适配SQLite场景,且不需要将超大数据集拉取到本地,所有操作都在数据库端执行:
library(RSQLite) library(dplyr) library(dbplyr) db <- dbConnect(SQLite(), dbname = "ukbb.sqlite") bd <- tbl(db, "Uk_Bb") # 重编码逻辑 bd_encoded <- bd %>% mutate(f.19.0.0 = case_when( f.19.0.0 == 1 ~ "Direct entry", f.19.0.0 == 2 ~ "Manual entry", f.19.0.0 == 3 ~ "Not performed", f.19.0.0 == 6 ~ "Not performed - equipment failure", f.19.0.0 == 7 ~ "Not performed - other reason", TRUE ~ NA_character_ # 对应你原本的.default=NULL需求,设置为字符型缺失值 )) # 若后续需要将处理后的数据拉取到本地内存,再调用collect(),大数据集建议先完成过滤、聚合等操作再拉取 # bd_local <- bd_encoded %>% collect()
如果坚持要使用recode,可以调整写法(部分SQLite版本仍可能存在兼容问题,不如case_when稳妥):
bd %>% mutate(f.19.0.0 = recode(f.19.0.0, `1` = "Direct entry", `2` = "Manual entry", `3` = "Not performed", `6` = "Not performed - equipment failure", `7` = "Not performed - other reason", .default = NA_character_))
内容的提问来源于stack exchange,提问作者DreamNet
相关产品推荐
相关产品推荐

