如何生成指示ID是否出现在月度数据中的哑变量?
问题描述
我有如下结构的DataFrame:
id date 1 1 2021-07-06 2 2 2021-07-10 3 4 2021-07-14 4 5 2021-07-18 5 8 2021-07-22 6 10 2021-07-26 7 11 2021-07-30 8 1 2021-08-03 9 2 2021-08-07 10 3 2021-08-11 11 5 2021-08-15 12 8 2021-08-19 13 9 2021-08-23 14 10 2021-08-27 15 12 2021-08-31 16 1 2021-09-04 17 3 2021-09-08 18 4 2021-09-12 19 6 2021-09-16 20 7 2021-09-20 21 8 2021-09-24
需要生成一个新的DataFrame,每行对应一个唯一ID,新增列以月份缩写命名(jul、aug、sep),用1/0标记该ID是否在对应月份出现过,最终结果如下:
id jul aug sep 1 1 1 1 1 2 2 1 1 0 3 3 0 1 1 4 4 1 0 1 5 5 1 1 0 6 6 0 0 1 7 7 0 0 1 8 8 1 1 1 9 9 0 1 0 10 10 1 1 0 11 11 1 0 0 12 12 0 1 0
初始DataFrame的生成代码:
df_start <- structure(list(id1 = c(1, 2, 4, 5, 8, 10, 11, 1, 2, 3, 5, 8, 9, 10, 12, 1, 3, 4, 6, 7, 8), date = structure(c(18814, 18818, 18822, 18826, 18830, 18834, 18838, 18842, 18846, 18850, 18854, 18858, 18862, 18866, 18870, 18874, 18878, 18882, 18886, 18890, 18894), class = "Date")), class = "data.frame", row.names = c(NA, -21L))
解决方法
方法一:使用tidyverse工具链
借助dplyr和tidyr完成数据转换,步骤清晰易读:
library(tidyverse) df_result <- df_start %>% # 提取月份缩写并转为小写 mutate(month = tolower(format(date, "%b"))) %>% # 去重,避免同一ID在同月多次出现的干扰 distinct(id1, month) %>% # 转换为宽表,用1标记存在,缺失值填充为0 pivot_wider(names_from = month, values_from = month, values_fn = ~1, values_fill = 0) %>% # 重命名id列为需求格式 rename(id = id1) # 查看最终结果 print(df_result)
方法二:使用Base R实现
无需额外加载包,通过基础函数完成转换:
# 提取月份缩写并转为小写 df_start$month <- tolower(format(df_start$date, "%b")) # 生成交叉表,先去重再统计出现情况 xtab <- table(unique(df_start[c("id1", "month")])) # 转换为数据框并调整格式 df_result <- as.data.frame.matrix(xtab) df_result$id <- rownames(df_result) # 调整列顺序为需求格式 df_result <- df_result[, c("id", "jul", "aug", "sep")] rownames(df_result) <- NULL # 查看最终结果 print(df_result)
内容的提问来源于stack exchange,提问作者bricevk
相关产品推荐
相关产品推荐

