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

Dplyr rename_with报列名重复错误 自定义函数实际生成唯一列名

报错核心原因

rename_with的逻辑是把选中的所有列名拼成一个字符向量,一次性传入你给的重命名函数,和sapply逐个传入单个列名的运行逻辑完全不同。
你写的renameCol是按单值输入设计的:函数里写死了取str_match_all返回结果的第一个元素[[1]],当一次性传入4个列名时,str_match_all会返回长度为4的匹配列表,你只提取了第一个列名对应的匹配结果,导致4个列全被重命名为Switch_11,自然触发列名重复的报错。
sapply运行时每次只传1个列名进函数,[[1]]取到的永远是当前传入列名的匹配结果,所以不会出问题。

修复方案

二选一即可:

  • 方案1:把函数改成支持向量输入,适配rename_with的传参逻辑,这是最稳妥的写法
library(tidyverse)
renameCol = function(colname)
{
  # 改用支持向量输入的str_match,不用固定取列表第一个元素
  match_res = str_match(colname, "HealthcareProvider(?:TaxonomyCode|PrimaryTaxonomySwitch)_([0-9]+)")
  coltype = str_remove(match_res[,2], "^(Taxonomy|PrimaryTaxonomy)")
  col_num = match_res[,3]
  return(paste0(coltype, "_", col_num))
}

tb = tibble(
  HealthcareProviderPrimaryTaxonomySwitch_11 = 1,
  HealthcareProviderTaxonomyCode_3 = 2,
  HealthcareProviderPrimaryTaxonomySwitch_9 = 3,
  HealthcareProviderTaxonomyCode_13 = 4
)

# 测试运行
tb %>% rename_with(renameCol)

运行后正常输出:

# A tibble: 1 × 4
  Switch_11 Code_3 Switch_9 Code_13
      <dbl>  <dbl>    <dbl>   <dbl>
1         1      2        3       4
  • 方案2:不想修改原有renameCol函数的话,在rename_with里套一层逐元素处理的逻辑,模拟sapply的传参效果
# 写法1:套sapply逐列处理
tb %>% rename_with(~sapply(.x, renameCol, USE.NAMES = FALSE))

# 写法2:用Vectorize把原函数转成支持向量输入的版本
tb %>% rename_with(Vectorize(renameCol))

两种写法都能得到和手动赋值colnames完全一致的结果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 07:01:26