如何使用tidyverse将多选字符列转换为数值指示列?
多选问题数据格式转换方案
Tidyverse 实现
利用tidyverse的pivot_longer和pivot_wider函数完成宽表到标记列的转换,步骤清晰简洁:
library(tidyverse) # 原始数据 pet_tab <- tibble( owner = 1:5, pet_1 = c("dog", "cat", "ferret", "dog", "snake"), pet_2 = c("cat", "ferret", NA, "ferret", NA), pet_3 = c("ferret", NA, NA, "snake", NA), pet_4 = c("snake", NA, NA, NA, NA) ) # 格式转换 pet_tab_clean <- pet_tab %>% # 将所有pet_*列转为长格式,丢弃原列名,仅保留宠物类型 pivot_longer(cols = starts_with("pet_"), names_to = NULL, values_to = "pet") %>% # 移除无宠物的NA行 drop_na(pet) %>% # 转回宽格式,以owner为分组,宠物类型为列名,存在标记1,不存在填充0 pivot_wider( id_cols = owner, names_from = pet, values_fn = ~1, values_fill = 0 ) # 输出结果 print(pet_tab_clean)
执行后会得到目标格式的数据,每列对应一种宠物,值为1表示该主人饲养对应宠物,0表示未饲养。
Data.table 实现
如果习惯用data.table,可以通过melt和dcast组合完成转换,效率更高:
library(data.table) # 转换为data.table对象 setDT(pet_tab) # 格式转换 pet_tab_clean_dt <- dcast( # 转长格式并过滤NA值 melt(pet_tab, id.vars = "owner", value.name = "pet")[!is.na(pet)], # 按owner分组,宠物类型为列,统计出现次数(1或0) owner ~ pet, fun.aggregate = length, fill = 0 ) # 输出结果 print(pet_tab_clean_dt)
这里melt将宽表转长,dcast转回宽表时用length统计每个宠物的出现次数(每个宠物最多出现一次,因此结果为1或0),fill=0确保未出现的宠物列填充0。
内容的提问来源于stack exchange,提问作者conflictcoder
相关产品推荐
相关产品推荐

