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

R Tidyverse 批量自动识别合并tibble带...后缀的重复列

问题原因

使用read_delim()读取分隔符不规范的文件时,字段内存在未被识别的分隔符会导致单列被错误拆分为多列,readr会自动给重名列追加...2、...3格式的后缀。
之前尝试的固定截取列名前7位+group_by()的方案报错核心原因有两点:

  • group_by()是对数据的行维度做分组,输入的列名向量长度等于数据列数(示例中为10),和数据行数(示例中为407400)不匹配,触发长度校验错误
  • 固定截取前7位列名的逻辑鲁棒性极差,列名长度变化时会将完全无关的字段错误归为同一组,无法适配多文件批量处理的场景
实现代码

以下方案可自动识别同源拆分列,无需手动指定列位置或列名,完全匹配合并规则,可直接嵌入for循环做批量处理:

library(tidyverse)

merge_split_cols <- function(df) {
  # 正则匹配移除列名末尾readr自动添加的...数字后缀,得到原始同源列名
  raw_col_names <- str_remove(names(df), "\\.\\.\\.\\d+$")
  # 按原始列名拆分列索引分组
  col_groups <- split(seq_along(df), raw_col_names)
  
  merged_cols <- map(col_groups, function(idx) {
    # 仅出现1次的非重复列直接原样返回
    if (length(idx) == 1) return(df[[idx]])
    
    sub_data <- df[, idx]
    # 数值类型列按规则合并:单非NA取该值、多非NA取均值、全NA返回NA
    if (all(map_lgl(sub_data, is.numeric))) {
      merged_val <- rowMeans(sub_data, na.rm = TRUE)
      merged_val[is.nan(merged_val)] <- NA
      return(merged_val)
    }
    
    # 非数值类型列逐行取第一个非NA值,适配字符、时间等类型列的拆分场景
    apply(sub_data, 1, function(row) {
      valid_val <- row[!is.na(row)]
      if (length(valid_val) == 0) return(NA)
      return(valid_val[1])
    })
  })
  
  # 拼装为最终tibble,保留原始列名
  as_tibble(merged_cols, .name_repair = "minimal")
}

# 调用示例:处理单个数据框
# df_clean <- merge_split_cols(df)

# 批量处理多文件时,在循环中读取文件后直接调用该函数即可
方案说明
  • 同源列识别通过正则匹配后缀实现,不依赖固定列名长度、固定列位置,不同文件的拆分列位置、数量变化都能自动适配
  • 数值列合并使用rowMeans(na.rm = TRUE)实现,天然匹配需求规则:单行仅1个非NA值时计算结果就是该值,多个非NA值时自动计算均值,全NA时将返回的NaN替换为NA即可
  • 非重复列不做任何处理,完全保留原有内容、数据类型和属性,比如示例中的Date&Time、SNOWTHERMO#1#TS0_30MIN_MEAN这类列不会被修改
  • 兼容非数值类型的拆分列场景,避免时间、字符类列被强制转数值报错

测试验证:对示例数据中的SNOWDEPTH#1#HS...2和SNOWDEPTH#1#HS...3列,合并后第一行值为0、第二行值为10、第三行值为9、第四行值为NA,和预期结果完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 11:15:29