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

R设置过高scipen致dplyr::across报错的原因与解决方法

问题概述
  • 触发场景:使用R语言dplyr包的across()函数做数据处理时运行报错,经排查问题与R全局选项scipen的设置直接相关。
  • 触发条件:为禁止数值以科学计数法格式输出,将scipen设置为极高值1e10时,dplyr::across()运行抛出错误;将scipen调整为1000这类较低取值时,代码可正常运行。
报错复现

可通过以下代码稳定复现问题:

library(tidyverse)
options(scipen=1e10)

# 构造测试数据
gdf <-
  tibble(g = c(1, 1, 2, 3), v1 = 10:13, v2 = 20:23) %>%
  group_by(g)

set.seed(1)

# 提前生成随机数
n <- rnorm(1)
gdf %>% mutate(across(v1:v2, ~ .x + n))

运行后抛出错误信息如下:

Error in local_error_context(dots = dots, .index = i, mask = mask) : 
  promise already under evaluation: recursive default argument reference or earlier problems?
正常运行示例

将scipen调整为合理较低值后代码可正常运行:

options(scipen=1000)
gdf %>% mutate(across(v1:v2, ~ .x + n))

运行输出:

# A tibble: 4 × 3
# Groups:   g [3]
      g    v1    v2
  <dbl> <dbl> <dbl>
1     1  9.37  19.4
2     1 10.4   20.4
3     2 11.4   21.4
4     3 12.4   22.4
问题原因

scipen是R中控制数值输出格式的全局选项,本质是一个整数类型的惩罚值:取值越大,R越倾向于使用固定小数格式输出数值、避免科学计数法。该选项的设计有效取值为常规范围的整数,传入1e10这类双精度浮点型的极大值时,会在dplyr的非标准求值流程中,干扰内部错误上下文处理函数local_error_context的默认参数匹配逻辑,触发promise递归求值锁冲突,最终抛出错误。
实际上scipen取值只要大于20,就已经可以覆盖绝大多数日常场景下禁止科学计数法的需求,设置到1e10属于完全不必要的极端取值,本身不符合该选项的参数设计预期。

可行解决方法
  • 合理设置scipen取值:日常使用如果需要禁止科学计数法输出,执行options(scipen = 999)即可满足需求,该取值既不会触发科学计数法,也不会因取值异常干扰其他包的内部运行逻辑,不要为该选项设置超过常规整数范围的极端大值。
  • 特殊数值格式化需求单独处理:如果需要对超大数值做固定格式输出,不要通过全局修改scipen为极端值的方式实现,可在数据处理完成后,通过format()、prettyNum()等格式化函数单独控制列的输出格式,避免全局选项对包内部求值逻辑造成干扰。
  • 异常恢复:如果已经因设置极端scipen值触发报错,先执行options(scipen = 999)重置全局选项,再重新运行dplyr相关代码即可恢复正常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 18:48:41