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

如何在R语言中对多列(超过两列)使用union函数?

问题:提取data.frame多列中的唯一值

需要比较data.frame中的列,识别多列里的唯一值。将多个体数据从长格式转宽格式后,想获取每个个体的所有唯一值。示例数据如下:

df <- data_frame(ID=rep(1:10,3), Value = as.character(rep(list("A1,B7,B11,C2","A1,B5,B8,D3",""),10)))

已编写的代码仅能处理生成的前两列,不确定如何纳入第三列(或更多列,通常有5列及以上):

df %>%
  mutate(across(Value, ~na_if(., ""))) %>%
  within({time <- ave(ID, list=ID, FUN=seq_along)}) %>% 
  pivot_wider(id_cols="ID",names_from="time",names_prefix="Value",values_from="Value") %>%
  rowwise() %>%
  mutate(Value = union(
    str_split(Value1, ",", simplify = TRUE),
    str_split(Value2, ",", simplify = TRUE)
  ) |> str_c(collapse = ", "))

曾考虑用循环将新列与前一次循环的输出对比,但希望找到更简便的方法。

解决方法

可以用c_across()配合tidyverse的函数统一处理所有目标列,无需手动指定列名,适用于任意数量的列:

library(tidyverse)

df <- tibble(ID=rep(1:10,3), Value = as.character(rep(list("A1,B7,B11,C2","A1,B5,B8,D3",""),10)))

df %>%
  # 把空字符串转为NA
  mutate(Value = na_if(Value, "")) %>%
  # 按ID分组,生成时间序号
  group_by(ID) %>%
  mutate(time = row_number()) %>%
  ungroup() %>%
  # 转宽格式
  pivot_wider(id_cols = ID, names_from = time, names_prefix = "Value", values_from = Value) %>%
  rowwise() %>%
  # 处理所有Value开头的列:过滤NA、拆分字符串、去重
  mutate(
    # 先存为列表格式,保留向量结构
    unique_values = list(
      c_across(starts_with("Value")) %>% 
        discard(is.na) %>% 
        str_split(",") %>% 
        flatten_chr() %>% 
        unique()
    )
  ) %>%
  # 可选:将列表转为逗号分隔的字符串
  mutate(unique_values_str = str_c(unique_values, collapse = ", ")) %>%
  ungroup()

关键步骤说明

  • c_across(starts_with("Value")):一次性选中所有以Value开头的列,不管后续新增多少列都能自动适配
  • discard(is.na):过滤掉空字符串转成的NA值,避免拆分出空内容
  • str_split(",") %>% flatten_chr():把所有列的字符串拆分后合并成一维向量
  • unique():对合并后的向量去重,得到每个个体的所有唯一值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 13:06:03