You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对R中多特征多标签的多行数据进行独热编码

多标签分组独热编码优化方案

问题背景

现有包含多个分类特征的数据,每条记录的多标签分布在多行中,示例数据如下:

myDf <- data.frame(myGroup = c("A", "B", "B", "C", "C", "C"),
                   myFruit = as.factor(c("apple", "apple", "banana", "apple", "lime", "lemon")),
                   myCode = as.factor(c("AAA", "AAA", "CCC", "AAA", "BBB", "CCC")))

数据预览:

myGroup myFruit myCode
      A   apple    AAA
      B   apple    AAA
      B  banana    CCC
      C   apple    AAA
      C    lime    BBB
      C   lemon    CCC

期望将数据按myGroup分组,把myFruit和myCode的所有类别转为独热编码列,1表示该分组包含对应类别,0表示不包含,输出如下:

myGroup apple banana lemon  lime   AAA   BBB   CCC
A           1      0     0     0     1     0     0
B           1      1     0     0     1     0     1
C           1      0     1     1     1     1     1

需求:寻找高效实现方式,避免对20个字段重复使用mutate/spread操作。


解决方案

方法1:tidyverse 长表转宽表(推荐,适配多字段场景)

利用pivot_longer将所有需要编码的分类字段合并为长格式,再用pivot_wider转成宽格式的独热编码,最后按myGroup聚合取最大值(确保分组内只要出现过就标记为1):

library(tidyverse)

myDf %>%
  pivot_longer(cols = -myGroup, names_to = "category", values_to = "value") %>%
  mutate(flag = 1) %>%
  pivot_wider(names_from = value, values_from = flag, values_fill = 0) %>%
  group_by(myGroup) %>%
  summarise(across(everything(), max))

这个方法不管有多少个分类字段,只需要修改pivot_longer的cols参数(比如cols = c(myFruit, myCode, ...)),无需重复操作,扩展性极强。

方法2:data.table 高效处理(大数据场景首选)

如果数据量较大,用data.table的速度优势更明显:

library(data.table)

setDT(myDf)
# 转长表
long_dt <- melt(myDf, id.vars = "myGroup", variable.name = "category", value.name = "value")
# 生成独热编码并聚合
dcast(long_dt, myGroup ~ value, fun.aggregate = max, fill = 0)

同样只需指定id.vars,其余分类字段自动参与转换,适合大规模数据处理。

方法3:自定义函数批量处理(兼容老版本工具)

如果不想用长表转换,也可以写一个批量处理函数,自动生成每个分类字段的独热列,再按分组聚合:

encode_multilabel <- function(df, group_col, cat_cols) {
  result <- df %>% select(all_of(group_col))
  for (col in cat_cols) {
    temp <- df %>%
      select(all_of(c(group_col, col))) %>%
      mutate(flag = 1) %>%
      pivot_wider(names_from = !!sym(col), values_from = flag, values_fill = 0) %>%
      group_by(!!sym(group_col)) %>%
      summarise(across(-!!sym(group_col), max))
    result <- result %>% left_join(temp, by = group_col)
  }
  return(result %>% distinct())
}

# 使用示例
encode_multilabel(myDf, "myGroup", c("myFruit", "myCode"))

这个函数可以直接传入需要编码的字段列表,无需手动重复写mutate/spread。


内容的提问来源于stack exchange,提问作者M.Viking

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 05:54:23