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

在R语言中如何根据另一列的值将数据框多列合并为单列?

基于Step列值合并多列为单列的简洁R语言解法

需求说明

现有数据框df,需根据Step列的取值,将指定列的内容提取到新列AA中,规则如下:

  • Step=1时,提取STA_AA列的值
  • Step=2时,提取INT_AA1列的值
  • Step=3时,提取INT_AA2列的值
  • Step=4时,提取END_AA列的值

最终保留POSITION、Step和AA三列。

输入数据

df <- structure(list(STA_AA = c("A", "A", "A", "A", "A", "A"), 
                     INT_AA1 = c("S", "G", "S", "S", "A", "A"), 
                     INT_AA2 = c("C", "C", "C", "S", "S", "G"), 
                     END_AA = c(NA, NA, "C", "C", "C", "C"), 
                     POSITION = c(221L, 221L, 221L, 221L, 221L, 221L), 
                     Step = c(1, 2, 3, 4, 1, 2)), 
                row.names = c(NA, 6L), class = "data.frame")

输入数据直观展示:

STA_AA INT_AA1 INT_AA2 END_AA POSITION Step
1      A       S       C   <NA>      221    1
2      A       G       C   <NA>      221    2
3      A       S       C      C      221    3
4      A       S       S      C      221    4
5      A       A       S      C      221    1
6      A       A       G      C      221    2

理想输出

op <- structure(list(POSITION = c(221L, 221L, 221L, 221L, 221L, 221L), 
                     Step = c(1, 2, 3, 4, 1, 2), 
                     AA = c("A", "G", "C", "C", "A", "A")), 
                row.names = c(NA, 6L), class = "data.frame")

直观展示:

POSITION Step AA
1      221    1  A
2      221    2  G
3      221    3  C
4      221    4  C
5      221    1  A
6      221    2  A

当前循环实现方法

使用foreach循环逐行判断赋值,代码如下:

library(tidyverse)
library(foreach)

df <- df %>% mutate(AA = NA)
foreach(j = 1:nrow(df)) %do% {
  if (df$Step[j] == 1) {
    df$AA[j] <- df$STA_AA[j]
  }
  if (df$Step[j] == 2) {
    df$AA[j] <- df$INT_AA1[j]
  }
  if (df$Step[j] == 3) {
    df$AA[j] <- df$INT_AA2[j]
  }
  if (df$Step[j] == 4) {
    df$AA[j] <- df$END_AA[j]
  }
}
df <- df %>% select(-STA_AA, -INT_AA1, -INT_AA2, -END_AA)

更简洁的解法

方法1:使用dplyr::case_when

利用case_when按条件批量赋值,无需循环,代码简洁易读:

library(dplyr)

df_result <- df %>%
  mutate(AA = case_when(
    Step == 1 ~ STA_AA,
    Step == 2 ~ INT_AA1,
    Step == 3 ~ INT_AA2,
    Step == 4 ~ END_AA,
    TRUE ~ NA_character_ # 处理Step不在1-4范围内的异常情况
  )) %>%
  select(POSITION, Step, AA)

方法2:使用rowwise + pick

通过建立Step与列名的映射关系,动态选取对应列的值,适配列名与Step有固定对应关系的场景:

library(dplyr)

# 建立Step到目标列名的映射
col_map <- c("1" = "STA_AA", "2" = "INT_AA1", "3" = "INT_AA2", "4" = "END_AA")

df_result <- df %>%
  rowwise() %>%
  mutate(AA = pick(all_of(col_map[as.character(Step)])) %>% pull()) %>%
  ungroup() %>%
  select(POSITION, Step, AA)

方法3:矩阵索引法(基础R实现)

无需加载额外包,利用矩阵索引直接提取对应位置的值,性能高效:

# 提取需要匹配的目标列
target_cols <- df[, c("STA_AA", "INT_AA1", "INT_AA2", "END_AA")]
# 生成索引矩阵:行号为数据框行序号,列号为Step的取值
idx <- cbind(1:nrow(df), df$Step)
# 提取对应值并创建AA列
df$AA <- target_cols[idx]
# 保留目标列
df_result <- df[, c("POSITION", "Step", "AA")]

以上三种方法均能高效完成需求,避免了循环带来的冗余代码,且在大数据量场景下性能更优。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 10:33:58