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

R语言如何按id分组将多列正值拆分为独立多行

R实现多列1值拆分为独热独立行方案

针对tibble中每行多个列取值为1、需要拆分为每行仅保留一个1值列其余置0的需求,最简洁的实现基于tidyverse工具链完成,代码可直接运行得到预期结果:

library(tidyverse)

# 示例输入数据
dat <- tibble(id = 1:4, 
              col1 = c(0, 1, 1, 0),
              col2 = c(1, 0, 1, 0),
              col3 = c(1, 1, 0, 1))

# 核心处理代码
result <- dat %>%
  pivot_longer(cols = starts_with("col"), names_to = "col_name", values_to = "val") %>%
  filter(val == 1) %>%
  pivot_wider(names_from = col_name, values_from = val, values_fill = 0) %>%
  select(id, col1, col2, col3)

运行后输出结果和预期完全一致:

> result
# A tibble: 7 × 4
     id  col1  col2  col3
  <dbl> <dbl> <dbl> <dbl>
1     1     0     1     0
2     1     0     0     1
3     2     1     0     0
4     2     0     0     1
5     3     1     0     0
6     3     0     1     0
7     4     0     0     1

处理逻辑拆解

  • 宽表转长表:将col1/col2/col3三个指标列的列名、取值拉平为长结构,原本一行多列的记录会拆分为「id+单个列名+对应取值」的多行条目
  • 过滤零值行:仅保留取值为1的记录,也就是每个id下原本为正值的列对应条目
  • 长表转回宽表:将过滤后的长表恢复为原表的列结构,没有匹配值的列通过values_fill = 0自动补0,自然实现每行仅一个列为1、其余同组列置0的效果
  • 调整列顺序:将输出列顺序和原始输入表对齐,保证格式统一

如果不想依赖tidyverse包,也可以用base R实现相同效果:

# base R 实现方案
col_vars <- grep("^col", names(dat), value = TRUE)
res_list <- apply(dat, 1, function(row) {
  id_val <- row[["id"]]
  one_cols <- names(which(row[col_vars] == 1))
  t(sapply(one_cols, function(oc) {
    new_row <- setNames(rep(0, length(col_vars)), col_vars)
    new_row[oc] <- 1
    c(id = id_val, new_row)
  }))
})
result <- as_tibble(do.call(rbind, res_list))

内容的提问来源于stack exchange,提问作者Maël

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 15:39:13