R语言如何用pivot_wider实现类别存在性布尔宽表转换
问题说明
现有如下测试数据框:
df <- data.frame(date = c('2021-01-05','2021-01-05','2021-01-10'), creature =c('bird','dog','dog'))
需求为调用pivot_wider函数,将creature字段的每个唯一值转换为单独列,按照对应日期下该生物类别是否存在,为每行填充TRUE或FALSE,期望得到的结果结构如下:
date creature bird dog <chr> <chr> <lgl> <lgl> 1 2021-01-05 bird TRUE TRUE 2 2021-01-05 dog TRUE TRUE 3 2021-01-10 dog FALSE TRUE
目前通过dplyr手动逐列编写判断逻辑可以实现需求,但当creature字段存在数十个水平时,逐列写逻辑的操作效率极低,需要确认是否可以直接通过pivot_wider完成该转换。当前手动实现的代码如下:
df %>% group_by(date) %>% mutate(bird = ifelse('bird' %in% creature,TRUE,FALSE), dog = ifelse('dog' %in% creature, TRUE,FALSE))
实现方案
完全可以直接通过pivot_wider适配任意数量的creature水平,无需手动逐列编写判断逻辑,参考代码如下:
library(tidyr) library(dplyr) df %>% group_by(date) %>% mutate(exist_creature = list(unique(creature))) %>% ungroup() %>% pivot_wider( names_from = creature, values_from = exist_creature, values_fn = ~ cur_column() %in% .x, values_fill = FALSE )
代码逻辑说明:
- 首先按
date分组,将当前日期下所有出现过的生物类别存入辅助列exist_creature - 调用
pivot_wider时,指定从creature字段提取新列名,通过values_fn配合cur_column()获取当前生成列对应的生物名称,判断其是否在当前行所属日期的已存在生物列表中,自动返回逻辑值 - 不存在的场景通过
values_fill = FALSE统一填充,无需额外分支判断 - 无论
creature字段有多少个唯一取值,代码都可以自动适配,不需要手动修改列名相关的判断逻辑。
内容的提问来源于stack exchange,提问作者Squan Schmaan
相关产品推荐
相关产品推荐

