使用dtplyr时recode函数触发‘零长度变量名’错误的求助
解决dtplyr中使用dplyr::recode时的零长度变量名错误
问题重现
样本数据
ACCOUNT <- c("M191212", "M205668", "M197954", "M208966", "M193465", "M207622", "M191869") PRODUCT <- c(1, 2, 3, 1, 2, 3, 2) data <- tibble(ACCOUNT, PRODUCT)
错误代码
library(tidyverse) library(data.table) library(dtplyr) data2 <- data %>% lazy_dt() %>% mutate(YR = substring(ACCOUNT,2,3)) %>% mutate(PRODUCT_NAME = dplyr::recode(PRODUCT, `1` = "PROD_A", `2` = "PROD_B", `3` = "PROD_C")) %>% collect()
报错信息
Error in env_has(env, var, inherit = TRUE) : attempt to use zero-length variable name
原因分析
dtplyr 1.2.1版本在处理lazy_dt对象时,对dplyr::recode的整数键解析存在兼容性问题。dtplyr会将dplyr语法转换为data.table语法,而recode的整数键在转换过程中出现解析错误,生成了无效的零长度变量名。
解决方案
方法1:用case_when替代recode
case_when在dtplyr中兼容性更好,逻辑直观:
data2 <- data %>% lazy_dt() %>% mutate(YR = substring(ACCOUNT,2,3)) %>% mutate(PRODUCT_NAME = case_when( PRODUCT == 1 ~ "PROD_A", PRODUCT == 2 ~ "PROD_B", PRODUCT == 3 ~ "PROD_C" )) %>% collect()
方法2:使用data.table原生替换语法
直接利用data.table的fcase函数,适配lazy_dt的转换逻辑:
data2 <- data %>% lazy_dt() %>% mutate(YR = substring(ACCOUNT,2,3)) %>% .[, PRODUCT_NAME := fcase( PRODUCT == 1, "PROD_A", PRODUCT == 2, "PROD_B", PRODUCT == 3, "PROD_C" )] %>% collect()
方法3:先转换为常规数据集再使用recode
如果数据集规模不大,可以先将lazy_dt转为tibble,再执行recode操作:
data2 <- data %>% lazy_dt() %>% mutate(YR = substring(ACCOUNT,2,3)) %>% collect() %>% mutate(PRODUCT_NAME = dplyr::recode(PRODUCT, `1` = "PROD_A", `2` = "PROD_B", `3` = "PROD_C"))
内容的提问来源于stack exchange,提问作者Pendragon
相关产品推荐
相关产品推荐

