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

基于多列值创建新变量:在R数据框中提取含1值的列名

解决R语言DataFrame生成新变量的需求

嘿,我来帮你搞定这个需求!先明确下你的目标:你有一个三列的DataFrame,要新增一个变量,每一行对应的值是该行里等于"1"的单元格所在的列名;如果一行没有"1"就返回NA,要是有多个"1",咱们还能把对应的列名用逗号拼接起来。

第一步:先确认你的原始数据

先把你的数据代码贴出来,方便后续操作:

MO1 <- c("0","1","2","3")
MO2 <- c("1","0","3","2")
MO3 <- c("3","2","1","0")
df <- data.frame(MO1, MO2, MO3)

方法一:用Base R快速实现

这是最直接的方案,用apply()函数逐行处理:

# 新增名为has_one的变量
df$has_one <- apply(df, 1, function(row) {
  # 筛选出当前行值为"1"的列名
  target_cols <- names(df)[row == "1"]
  # 处理不同情况:有匹配就拼接,没有就返回NA
  if (length(target_cols) > 0) {
    paste(target_cols, collapse = ", ")
  } else {
    NA_character_
  }
})

# 查看最终结果
print(df)

运行后你会得到预期结果:

MO1 MO2 MO3 has_one
1   0   1   3    MO2
2   1   0   2    MO1
3   2   3   1    MO3
4   3   2   0     <NA>

方法二:用Tidyverse工具链实现(适合熟悉tidy风格的用户)

如果你平时习惯用dplyr和tidyr,可以用宽转长的思路处理,这种方法更直观,也方便后续扩展:

library(dplyr)
library(tidyr)

df_new <- df %>%
  # 给每行加行号,方便后续分组
  mutate(row_id = row_number()) %>%
  # 把宽格式转成长格式
  pivot_longer(-row_id, names_to = "col_name", values_to = "value") %>%
  # 筛选出值为"1"的记录
  filter(value == "1") %>%
  # 按行号分组,拼接同一行的匹配列名
  group_by(row_id) %>%
  summarise(has_one = paste(col_name, collapse = ", ")) %>%
  # 合并回原始数据,保留所有行(包括无"1"的行)
  right_join(df %>% mutate(row_id = row_number()), by = "row_id") %>%
  # 去掉临时行号列
  select(-row_id) %>%
  # 把新变量移到最后一列,方便查看
  relocate(has_one, .after = last_col())

# 查看结果
print(df_new)

这个方法得到的结果和Base R方案完全一致,要是你的DataFrame列数多、后续还要做更多处理,这种tidy风格的代码会更易读和维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:11:38