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

如何用R的dcast/spread一次性将两列分类变量转宽表?

解决方法:一步实现长转宽(分两种常用方式)

先构造示例数据方便演示:

# 示例数据框
dat <- data.frame(
  bm = c(1,1,2,2),
  at4 = c("a","a","b","b"),
  n1 = c(10,20,30,40),
  cat = c("x","y","x","z"),
  clas = c("k","l","k","l")
)

你的需求是把cat(x/y/z)和clas(k/l)的所有取值单独作为列,匹配行填1、否则填0,不需要生成cat+clas的组合列。可以通过先把两个分类变量堆叠成统一的长格式,再转宽来一步完成,以下是两种实现方式:

方式1:用reshape2的dcast

先通过melt把cat和clas合并成一个变量,再用dcast转宽:

library(reshape2)

# 堆叠分类变量 + 生成标记列 + 转宽
result <- dcast(
  melt(dat, id.vars = c("bm", "at4", "n1"), measure.vars = c("cat", "clas"),
       variable.name = "type", value.name = "category") %>% mutate(temp1 = 1),
  bm + at4 + n1 ~ category,
  value.var = "temp1",
  fun.aggregate = sum,
  fill = 0
)

方式2:用tidyr的pivot_wider(tidyverse生态更推荐)

用pivot_longer堆叠变量,再用pivot_wider转宽,链式操作更直观:

library(tidyr)
library(dplyr)

result <- dat %>%
  # 把cat和clas堆叠成统一的category列
  pivot_longer(cols = c(cat, clas), names_to = "type", values_to = "category") %>%
  # 生成匹配标记列
  mutate(temp1 = 1) %>%
  # 转宽,按bm/at4/n1分组,category值作为列,不匹配填充0
  pivot_wider(
    id_cols = c(bm, at4, n1),
    names_from = category,
    values_from = temp1,
    values_fill = 0,
    values_fn = list(temp1 = sum)
  )

两种方法得到的结果一致,都会生成包含x/y/z/k/l列的数据框,匹配行填1,不匹配填0,无需分步调用转宽函数。

内容的提问来源于stack exchange,提问作者Korpo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 20:39:14