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

如何在R语言中用dplyr按行合并因子生成flavor列

问题:将多列非NA值合并为分类列(dplyr通用方案)

原始数据

df <- data.frame(id = c("001", "002", "003", "004"),
                 banana = c("banana", NA, NA, NA),
                 apple = c(NA, "apple", "apple", NA),
                 orange = c("orange", NA, NA, NA),
                 mango = c(NA, NA, NA, "mango"))

输出:

id banana apple orange mango
001 banana    NA orange    NA
002     NA apple     NA    NA
003     NA apple     NA    NA
004     NA    NA     NA mango

需求

将banana、apple、orange、mango列合并为名为flavor的新列:

  • 若一行有多个非NA值,标记为mixed
  • 若一行只有一个非NA值,取该值作为flavor内容
  • 方案需兼容数据框中存在其他列的情况

解决方案

方法1:rowwise + c_across(直观易读)

适合中小规模数据,代码逻辑清晰:

library(dplyr)

df_processed <- df %>%
  rowwise() %>%
  mutate(
    # 提取当前行目标列的非NA值
    non_na_vals = list(na.omit(c_across(banana:mango))),
    # 根据非NA值数量生成flavor
    flavor = case_when(
      length(non_na_vals) > 1 ~ "mixed",
      length(non_na_vals) == 1 ~ non_na_vals[[1]],
      TRUE ~ NA_character_ # 处理全NA的情况
    )
  ) %>%
  ungroup() %>%
  select(-non_na_vals) # 删除临时中间列

方法2:purrr::pmap(高效无rowwise)

适合大规模数据,避免rowwise的性能损耗:

library(dplyr)
library(purrr)

df_processed <- df %>%
  mutate(
    flavor = pmap_chr(select(., banana:mango), function(...) {
      non_na <- na.omit(c(...))
      case_when(
        length(non_na) > 1 ~ "mixed",
        length(non_na) == 1 ~ non_na,
        TRUE ~ NA_character_
      )
    })
  )

处理结果

df_processed
#>    id banana apple orange mango flavor
#> 1 001 banana    NA orange    NA  mixed
#> 2 002     NA apple     NA    NA  apple
#> 3 003     NA apple     NA    NA  apple
#> 4 004     NA    NA     NA mango  mango

通用性说明

  • 若目标列不连续,可将c_across(banana:mango)替换为c_across(c(banana, apple, orange, mango)),按需指定列名
  • 两种方法都会保留数据框中的其他列,无需额外处理
  • 自动处理全NA的行,返回NA_character_

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 16:32:31