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

R语言如何将var_前缀列的非零值与列名合并为新列?

R语言生成自定义res列的实现方案

问题描述

现有如下R数据框:

var_1 <- c(10, 5, 6, 0)
var_2 <- c(0, 0, 3, 0)
var_3 <- c(2, 0, 9, 0)
df <- data.frame(var_1, var_2, var_3)

原始输出:

var_1 var_2 var_3
1    10     0     2
2     5     0     0
3     6     3     9
4     0     0     0

需要新增一列res,规则:

  • 提取每行中var_前缀列的非零值,格式为「列名(值)」,多值用逗号分隔
  • 整行全为0时,res设为NA

注:原示例第三行res仅显示var_2 (3)疑似笔误,按规则应包含所有非零值,最终期望结果如下:

var_1 var_2 var_3                               res
1    10     0     2            var_1 (10), var_3 (2)
2     5     0     0                        var_1 (5)
3     6     3     9 var_1 (6), var_2 (3), var_3 (9)
4     0     0     0                             <NA>

实现方法

方法1:使用tidyverse工具链

借助dplyr的逐行处理能力,结合stringr格式化字符串:

library(tidyverse)

df <- df %>%
  rowwise() %>%
  mutate(
    # 筛选非零值,生成「列名(值)」格式的字符串列表
    res = list(str_c(
      names(.)[c_across(starts_with("var_")) != 0],
      " (", c_across(starts_with("var_"))[c_across(starts_with("var_")) != 0], ")",
      sep = ""
    )),
    # 空列表转为NA,否则合并为逗号分隔的字符串
    res = case_when(
      length(unlist(res)) == 0 ~ NA_character_,
      TRUE ~ str_c(unlist(res), collapse = ", ")
    )
  ) %>%
  ungroup()

方法2:基础R实现

无需额外包,用apply逐行处理:

# 定义行处理函数
format_res <- function(row_data) {
  non_zero_pos <- row_data != 0
  if (all(!non_zero_pos)) return(NA_character_)
  
  # 生成每个非零值的格式化字符串
  formatted_strs <- paste0(
    names(row_data)[non_zero_pos],
    " (", row_data[non_zero_pos], ")"
  )
  # 合并为单个字符串
  paste(formatted_strs, collapse = ", ")
}

# 应用到所有行
df$res <- apply(df[, startsWith(names(df), "var_")], 1, format_res)

两种方法都能生成符合要求的res列,可根据自身包依赖习惯选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 16:42:46