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

R语言:基于二进制列生成标记值为1的列名的新列集合

解决方案:提取每行取值为1的列名生成新列

你有一个包含0/1二进制列的数据框,需要为每行生成若干path_*列,依次记录该行中值为1的原始列名,无对应值则为空。先看你的输入数据:

df <- data.frame(ID = c(1, 2, 3),
                 `1_0_1_0` = c(1, 0, 0), `1_0_0_0` = c(0, 0, 1),
                 `2_0_1_0` = c(1, 1, 0), `2_0_3_0` = c(0, 0, 0),
                 check.names = FALSE)

对应的期望输出示例:

ID    path_1    path_2
1  1 1_0_1_0 2_0_1_0
2  2 2_0_1_0         
3  3 1_0_0_0         

下面提供两种可行的实现方法:

方法1:Base R 实现

通过遍历每行筛选目标列名,再整理成对应格式:

# 提取所有二进制列(排除ID列)
binary_cols <- setdiff(names(df), "ID")

# 逐行获取值为1的列名
path_list <- apply(df[binary_cols], 1, function(x) names(x[x == 1]))

# 确定需要生成的path列最大数量
max_paths <- max(sapply(path_list, length))

# 将列表转换为数据框,空位置补空字符
path_df <- do.call(rbind, lapply(path_list, function(x) {
  length(x) <- max_paths
  x[is.na(x)] <- ""
  x
}))

# 重命名path列
colnames(path_df) <- paste0("path_", 1:max_paths)

# 合并原ID列与新生成的path列
result <- cbind(df["ID"], path_df)

# 查看结果
print(result)

方法2:tidyverse 实现

用管道式操作完成长格式与宽格式的转换:

library(dplyr)
library(tidyr)

result <- df %>%
  # 将二进制列转为长格式
  pivot_longer(cols = -ID, names_to = "col_name", values_to = "value") %>%
  # 筛选值为1的记录
  filter(value == 1) %>%
  # 按ID分组,为每个分组内的列名添加序号
  group_by(ID) %>%
  mutate(path_num = paste0("path_", row_number())) %>%
  ungroup() %>%
  # 转回宽格式,空值填充""
  pivot_wider(id_cols = ID, names_from = path_num, values_from = col_name, values_fill = "") %>%
  # 确保所有原始ID都被保留
  right_join(df["ID"], by = "ID") %>%
  # 按ID排序
  arrange(ID)

print(result)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 13:45:10