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

使用mutate_at匹配指定列时遇“No tidyselect variables were registered”错误的解决方法

解决mutate_at报错:No tidyselect variables were registered

我来帮你搞定这个问题!你遇到的报错主要是因为在mutate_at中传递列名变量的方式不对,再加上mutate_at其实已经是dplyr的旧语法了,我会给你两种解决方案:一种修复你原来的mutate_at写法,另一种是更推荐的现代dplyr语法。

先理清问题根源

你定义的vars_to_match是精确的列名列表,但你用了matches()(这是用来做正则模糊匹配的),虽然理论上拼接成正则也能匹配,但这种方式在tidyselect上下文中容易出现变量注册问题,导致报错。另外,从dplyr 1.0.0版本开始,官方已经推荐用across()取代mutate_at/mutate_if等旧函数,后者现在只处于维护状态。

方案1:修复mutate_at的写法

用all_of()来精确匹配你指定的列名,这是传递变量列名最可靠的方式:

library(dplyr)
library(tidyr)

# 数据准备(和你原来的一致)
data(iris)
my_Data <- iris %>% mutate(row = row_number()) %>% pivot_wider(names_from = Species, values_from = Sepal.Length:Petal.Width)

# 标准化函数
Scale_Me <- function(x){
  (x - mean(x, na.rm = TRUE)) / sd(x, na.rm = TRUE)
}

# 要处理的列名
vars_to_match <- c("Petal.Length_virginica", "Sepal.Length_virginica", "Sepal.Width_setosa")

# 正确的mutate_at写法
my_Data %>% mutate_at(
  .vars = all_of(vars_to_match),
  .funs = list(Scaled = Scale_Me) # 用list指定新列的后缀,更清晰
)

这里all_of(vars_to_match)会精准定位你列出的列,避免正则匹配带来的不确定性,同时也能正确注册tidyselect变量,解决报错问题。

方案2:推荐使用mutate(across(...))现代语法

across()是dplyr现在主推的函数,功能更灵活,写法也更直观:

# 现代写法:用across处理指定列
my_Data %>% mutate(
  across(all_of(vars_to_match), Scale_Me, .names = "{.col}_scaled")
)
  • all_of(vars_to_match):精准选择目标列
  • Scale_Me:要应用的标准化函数
  • .names = "{.col}_scaled":自定义新列名,{.col}会自动替换成原列名,生成类似Petal.Length_virginica_scaled的新列,可读性更强

额外说明:如果需要模糊匹配列

如果你确实需要根据列名的模式(比如包含"virginica")来选择列,那可以用matches(),写法如下:

# 匹配所有包含"virginica"的列
my_Data %>% mutate(
  across(matches("virginica"), Scale_Me)
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:39:17