如何在R中为多标签变量生成按物品分组的颜色存在标记列
高效处理大数据集:物品-颜色二进制矩阵转换
针对你1000万条事件、800种颜色的大数据场景,推荐两种高效实现方式,优先用data.table处理,速度远快于tidyverse;如果习惯tidyverse,也有优化后的方案。
先处理原始数据中的字符串"NA"
你的数据集里tag列的"NA"是字符串类型,需要先转为真正的缺失值,避免被当成颜色:
# tidyverse方式 library(tidyverse) df <- df %>% mutate(across(starts_with("tag"), ~ifelse(.x == "NA", NA, .x))) # data.table方式 library(data.table) setDT(df) df[, (paste0("tag", 1:3)) := lapply(.SD, function(x) fifelse(x == "NA", NA_character_, x)), .SDcols = paste0("tag", 1:3)]
方法1:data.table(推荐,大数据下效率拉满)
data.table的melt和dcast是专门为大数据优化的函数,内存占用低、速度快:
# 1. 转长格式,过滤缺失值,去重(同一个物品的同一种颜色只保留一条) dt_long <- melt(df, id.vars = "item", measure.vars = paste0("tag", 1:3), variable.name = NULL, value.name = "color") %>% na.omit() %>% unique(by = c("item", "color")) # 2. 转宽格式,生成二进制列(存在=1,不存在=0) dt_wide <- dcast(dt_long, item ~ color, fun.aggregate = length, fill = 0) %>% setnames("item", "Item")
方法2:tidyverse(适合习惯dplyr/tidyr的用户)
通过pivot_longer+pivot_wider实现,注意加distinct去重提升效率:
# 1. 转长格式,过滤缺失值,去重 df_long <- df %>% select(item, starts_with("tag")) %>% pivot_longer(cols = starts_with("tag"), names_to = NULL, values_to = "color") %>% drop_na(color) %>% distinct(item, color) # 2. 转宽格式,生成二进制列 df_wide <- df_long %>% pivot_wider(names_from = color, values_from = color, values_fn = ~1, values_fill = 0) %>% rename(Item = item)
转换后结果示例
两种方法都会得到如下结构的输出(仅展示部分列):
| Item | red | blue | green | yellow |
|---|---|---|---|---|
| 1 | 1 | 1 | 0 | 0 |
| 2 | 0 | 1 | 0 | 0 |
| 3 | 1 | 0 | 1 | 1 |
| 4 | 1 | 0 | 0 | 1 |
| 5 | 1 | 0 | 1 | 0 |
内容的提问来源于stack exchange,提问作者haley
相关产品推荐
相关产品推荐

