关于R包collapse中across未导出及指定包函数的问题
核心问题:第二段代码的across来源
你在fsummarise中使用的across是collapse包内部实现的版本,并非dplyr的across。原因是collapse的fsummarise/fmutate等动词会在内部优先识别并解析自己的across逻辑,即使该函数未被导出到全局环境,也会在函数内部的上下文里生效,不会调用dplyr的同名函数。
为什么collapse::across未被导出?
collapse的across是内部专用的语法标记函数,设计初衷就是只能在fmutate()/fsummarise()这类collapse的核心动词内部使用:
- 从你查到的函数定义可以看到,它直接抛出错误提示:
说明它本身不具备独立执行的能力,只是作为一个标识,让collapse的动词识别需要批量处理列的逻辑。function (.cols = NULL, .fns, ..., .names = NULL, .apply = "auto", .transpose = "auto") { stop("across() can only work inside fmutate() and fsummarise()") } - 不导出的核心目的是避免命名冲突:dplyr的
across是用户广泛使用的函数,collapse不导出自己的across,可以防止用户在全局环境中调用时产生混淆,同时强制用户在collapse的工作流内使用该函数,保证和collapse的高效分组、优化函数(如fmean)的兼容性。
为什么指定命名空间调用会报错?
当你尝试直接用collapse::across或collapse:::across调用时:
mtcars %>% fgroup_by(cyl) %>% fsummarise(collapse:::across(.fns = fmean))
Error in fsummarise(., collapse:::across(.fns = fmean)) :
expressions need to be named or start with across(), or its shorthand acr().
这是因为fsummarise的内部解析逻辑只会识别裸函数名across或acr,不会识别带命名空间的调用形式——它是在内部上下文里处理这个函数的逻辑,而不是调用全局环境中带命名空间的函数。
指定特定包函数的替代方法
1. 使用collapse官方推荐的简写acr()
这是across的官方 shorthand,功能完全一致,且不会和dplyr的across混淆,是最推荐的方案:
mtcars %>% fgroup_by(cyl) %>% fsummarise(acr(.fns = fmean))
2. 明确指定.fns中的函数来源
如果需要确保批量处理时使用的是collapse的优化函数(如fmean),直接用::指定函数来源即可,across/acr会在collapse的上下文里正常处理:
mtcars %>% fgroup_by(cyl) %>% fsummarise(across(.fns = collapse::fmean))
3. 临时隔离dplyr的干扰(不推荐)
如果确实需要完全避免dplyr的across被误调用,可以临时detach dplyr,但这种方法会影响其他依赖dplyr的代码,仅作为极端情况的备选:
detach("package:dplyr", unload = TRUE) mtcars %>% fgroup_by(cyl) %>% fsummarise(across(.fns = fmean))
内容的提问来源于stack exchange,提问作者www

