使用case_when因列类型不一致报错的解决方案咨询
R语言case_when报错:must be a logical vector, not a double vector 解决办法
当用bind_rows拼接空数据框和包含部分列的子数据框后,空列会保留初始的logical类型,有值的列是double类型,此时使用case_when跨列取值时,因分支返回的向量类型不一致触发报错。
报错原因
case_when要求所有条件分支返回的向量类型完全一致。拼接后的a/c/d/e列是logical(空数据框初始化时默认类型),b列是double,混合不同类型的返回值会触发类型不匹配错误。
解决方案1:初始化空数据框时指定统一列类型
直接创建指定numeric类型的空数据框,从根源避免类型混乱:
# 初始化时直接指定各列为numeric类型,替代matrix默认的logical df <- data.frame(a = numeric(), b = numeric(), c = numeric(), d = numeric(), e = numeric()) df_subset <- data.frame(b=c(1,2)) df1 <- bind_rows(df, df_subset) %>% mutate(type="b") # 直接运行case_when即可 df1 %>% mutate(result=case_when( type=="a"~a, type=="b"~b, type=="c"~c, type=="d"~d, type=="e"~e, TRUE~NA_real_ ))
解决方案2:拼接后统一转换逻辑型列为数值型
如果无法修改初始化步骤,可在拼接后批量转换逻辑型列:
df <- setNames(data.frame(matrix(ncol = 5, nrow = 0)), c("a", "b", "c","d","e")) df_subset <- data.frame(b=c(1,2)) df1 <- bind_rows(df, df_subset) %>% mutate(type="b") %>% # 将所有逻辑型列转为数值型 mutate(across(where(is.logical), as.numeric)) # 运行case_when df1 %>% mutate(result=case_when( type=="a"~a, type=="b"~b, type=="c"~c, type=="d"~d, type=="e"~e, TRUE~NA_real_ ))
解决方案3:在case_when分支中强制统一类型
针对当前case_when场景,在每个分支中强制转换为数值型:
df <- setNames(data.frame(matrix(ncol = 5, nrow = 0)), c("a", "b", "c","d","e")) df_subset <- data.frame(b=c(1,2)) df1 <- bind_rows(df, df_subset) %>% mutate(type="b") df1 %>% mutate(result=case_when( type=="a"~as.numeric(a), type=="b"~as.numeric(b), type=="c"~as.numeric(c), type=="d"~as.numeric(d), type=="e"~as.numeric(e), TRUE~NA_real_ ))
预期输出
三个方案均会得到如下结果:
a b c d e type result 1 NA 1 NA NA NA b 1 2 NA 2 NA NA NA b 2
内容的提问来源于stack exchange,提问作者one
相关产品推荐
相关产品推荐

