R中对含逻辑、字符列的宽表用pivot_longer转长表报错如何解决
报错原因
tidyr::pivot_longer默认会将所有待拉长的列的值合并到同一个结果列中,要求待合并列的数据类型必须一致。你的数据中C1、C2是逻辑型(logical),C3是字符型(character),类型无法直接兼容,因此抛出错误。
另外你原始构造数据的代码存在两处笔误:
- 定义C2列时末尾误写为
;C1,会导致C2赋值错误 - C3列的取值
"wanrning"为拼写错误,正确应为"warning"
修正代码
两种方案均可实现需求,核心是将待拉长的列统一为相同数据类型(逻辑值转字符型不会丢失信息,完全满足存储要求)。
方案1:提前统一列类型
转换前先将所有需要拉长的列转为字符型,同时修正列名匹配要求的Check category、result字段:
library(tidyr) library(dplyr) library(tibble) # 构造原始数据(修正笔误) id = c(rep("A",3),rep("B",3)) month = c(1,2,3,1,2,3) C1 = c(T,F,F,T,F,T) C2 = c(F,F,T,T,F,F) C3 = c("ok","not","warning","not","not","ok") dat = tibble(id,month,C1,C2,C3) # 宽转长 dat_long <- dat %>% mutate(across(c(C1, C2, C3), as.character)) %>% pivot_longer( cols = !c(id, month), names_to = "Check category", values_to = "result" )
方案2:转换时指定类型转换规则
无需提前修改原数据列类型,通过values_transform参数在转换过程中统一结果列的类型:
dat_long <- dat %>% pivot_longer( cols = !c(id, month), names_to = "Check category", values_to = "result", values_transform = list(result = as.character) )
输出效果
转换后的数据每一行对应一个id+月份下的单个检查项,Check category列存储原C1/C2/C3的列名,result列存储对应取值,逻辑值会自动转换为"TRUE"/"FALSE"字符串,与C3的字符取值格式统一,完全符合预期结构。
内容的提问来源于stack exchange,提问作者Homer Jay Simpson
相关产品推荐
相关产品推荐

