如果在创建对象和评估对象之间环境发生变化,R 中的惰性评估会导致意外结果
Lazy evaluation in R leads to unexpected results if the environment changes between the time the object was created and the time it is evaluated
openxlsx 在其当前版本 4.2.4 中将数字精度从默认值 7 覆盖为 22。如果您尝试使用 writeData.data.frame 编写惰性评估 data.frame,这将导致意外行为。
library(openxlsx)
library(magrittr)
library(dplyr)
wb <- createWorkbook()
sheet <- addWorksheet(wb,"Sheet")
data.frame(a=55.7) %>% mutate(a=a%>%format(nsmall=1)) %>% writeData(wb,sheet,.)
saveWorkbook(wb,"test.xlsx")
您可能会看到,工作簿中包含的不是预期的字符串“55.7”,而是更多的小数。这是因为在全局环境中 format 使用 7 位数字,因此 format(55.7)=="55.7",但在 writeData 中它的计算结果为
格式(55.7)==“55.700000000000003”
这不是浮点数的问题,而是环境变化的问题。格式使用默认值“digits=getOption("digits")”。默认为 7,在 writeData 中为 22。仅此而已,没什么特别的。
我想知道,为什么 format(55.7) 没有在全局环境的上下文中得到评估。
我想这是 openxlsx
:
的一个特性(或错误)
- R 对象是相同的
- 这不是显示或格式的问题。我查看了这些文件的 XML,数字 55.70000000000000284217 和 57.7 是由 R 函数写入的
- 用
writexl
替换 openxlsx
消除了这种差异
使用当前环境中的数字选项延迟计算表达式。 openxlsx::writeData 某处使用 17 位数字,而默认值为 7。
library(magrittr)
f <- function(x) {
rlang::scoped_options(digits=17)
x$a
}
data.frame(a=format(1234.1)) %>% f()
> 1234.0999999999999
df <- data.frame(a=format(1234.1))
df %>% f()
> 1234.1
编辑:来自 openxlsx 的开发人员确认了该行为。他们通过在更改 fix.
中的任何环境变量之前强制评估其输入 data.frame 来解决此问题
这里是 link to my next question,它显示了完全相同的意外行为,但没有使用数字。
openxlsx 在其当前版本 4.2.4 中将数字精度从默认值 7 覆盖为 22。如果您尝试使用 writeData.data.frame 编写惰性评估 data.frame,这将导致意外行为。
library(openxlsx)
library(magrittr)
library(dplyr)
wb <- createWorkbook()
sheet <- addWorksheet(wb,"Sheet")
data.frame(a=55.7) %>% mutate(a=a%>%format(nsmall=1)) %>% writeData(wb,sheet,.)
saveWorkbook(wb,"test.xlsx")
您可能会看到,工作簿中包含的不是预期的字符串“55.7”,而是更多的小数。这是因为在全局环境中 format 使用 7 位数字,因此 format(55.7)=="55.7",但在 writeData 中它的计算结果为
格式(55.7)==“55.700000000000003”
这不是浮点数的问题,而是环境变化的问题。格式使用默认值“digits=getOption("digits")”。默认为 7,在 writeData 中为 22。仅此而已,没什么特别的。
我想知道,为什么 format(55.7) 没有在全局环境的上下文中得到评估。
我想这是 openxlsx
:
- R 对象是相同的
- 这不是显示或格式的问题。我查看了这些文件的 XML,数字 55.70000000000000284217 和 57.7 是由 R 函数写入的
- 用
writexl
替换openxlsx
消除了这种差异
使用当前环境中的数字选项延迟计算表达式。 openxlsx::writeData 某处使用 17 位数字,而默认值为 7。
library(magrittr)
f <- function(x) {
rlang::scoped_options(digits=17)
x$a
}
data.frame(a=format(1234.1)) %>% f()
> 1234.0999999999999
df <- data.frame(a=format(1234.1))
df %>% f()
> 1234.1
编辑:来自 openxlsx 的开发人员确认了该行为。他们通过在更改 fix.
中的任何环境变量之前强制评估其输入 data.frame 来解决此问题这里是 link to my next question,它显示了完全相同的意外行为,但没有使用数字。