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

使用dplyr为任意列应用自定义函数报错的原因及解决方法问询

自定义trim_whitespace函数报错'island' not found的原因与修复

问题重现

library(tidyverse)
library(palmerpenguins)

trim_whitespace <- function(.data, ...) {
  .data |> mutate(across(..., \(x) str_remove_all(x, "\\s")))
}

# 在字符列末尾添加空格
penguins_with_whitespace <- 
  penguins |> 
  mutate(across(c(species, island), \(x) paste0(x, " ")))

penguins_with_whitespace |> trim_whitespace(species, island)

运行后报错:'island' not found

错误原因

问题出在整洁求值(tidy eval)的上下文绑定上:

  • 你通过...传递的species、island是裸列名,默认会在函数的全局环境中查找这些对象,而非传入的.data数据框内部环境。
  • across()需要识别数据框内的列选择器,但当前写法没有将列名的求值上下文绑定到数据框,导致R误认为你要找全局环境中名为species或island的独立对象,自然找不到。

修复方法

两种简洁的修复方式,核心都是让R明确你传递的是数据框内的列名:

方法1:使用准引用{{}}(推荐)

通过{{}}(准引用语法)捕获...中的列名,将它们的求值上下文绑定到目标数据框:

trim_whitespace <- function(.data, ...) {
  .data |> mutate(across({{...}}, \(x) str_remove_all(x, "\\s")))
}

方法2:使用enquos()和!!!(展开引用)

先通过enquos()捕获...中的所有列名引用,再用!!!(展开操作符)传递给across():

trim_whitespace <- function(.data, ...) {
  target_cols <- enquos(...)
  .data |> mutate(across(!!!target_cols, \(x) str_remove_all(x, "\\s")))
}

修复后再次执行penguins_with_whitespace |> trim_whitespace(species, island),即可正确去除指定列的空格。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 21:27:41