R POST 使用 Plumber API 的响应在客户端将 10-decimal-places double(所需精度)转换为 4-decimal-places double
R POST response using Plumber API converts 10-decimal-places double (desired precision) to 4-decimal-places double at client side
平台:
- 具有 16 个内核和 128 GIG RAM 的 AWS 实例。
- 红帽企业 7.5。
-R。
- RStudio 服务器。
- 管道工 API 将 R 函数公开为 Web 服务端点。
- 客户端是 Excel VBA.
问题:
- 具有不同类型列的数据 table,包括双精度、整数和字符串数据。
- 就在 R 端点函数发送响应(table)之前,当我检查数据 table 中的双精度数据时,所有条目的长度都在 6 到 10 decimal-place 之间。
- 一旦 table 以 JSON 格式到达客户端,99% 的双列将四舍五入为 4 decimal-place 长。
知道可能是什么问题 - 为什么双打会四舍五入,四舍五入发生在什么地方,我该如何防止这种情况?
- 我尝试了不同的请求 header 设置,但没有成功。
- 我试图将受影响的双 column/s 作为 vector/s 或 list/s 发送,但我得到相同的 "enforced" 舍入。
提前致谢
这没有很好的记录,但事实证明这是在 jsonlite::toJSON
序列化程序 (digits = 4
) 中使用默认值的结果。这里有一些细节:
https://www.rplumber.io/articles/rendering-output.html
我看不出如何从参数化中将参数传递给它,但这里有一个解决方法:
library(plumber)
#* @apiTitle A Test API
#* Run a simple function
#* @get /
function(req, res) {
x <- rnorm(1)
res$body <- jsonlite::toJSON(x, digits = NA)
res
}
# plumb("plumber_1.R")$run(port = 5762)
# Save this file as e.g. "plumber_1.R" and run the commented line
那么你应该能够得到这样的回复:
library(httr)
y <- GET("http://127.0.0.1:5762/")
content(y, as = "text")
[1] "[-0.982448323838634]"
因此,无论函数的结果是什么,使用 jsonlite::toJSON(..., digits = NA)
对其进行预序列化,并将其直接存储在响应主体中,然后 return 响应对象。
事实证明有一种“正确”的方法可以做到这一点,我通过将其归档为 GitHub 问题 https://github.com/trestletech/plumber/issues/403 发现了这一点。但是,看起来这个版本还没有在 CRAN 上,所以您可以同时使用上面的修复程序。
在您的 API 定义中,像这样指定序列化程序:
#' @serializer json list(digits = 12)
或 json 特别是
#' @json(digits = 12)
平台: - 具有 16 个内核和 128 GIG RAM 的 AWS 实例。 - 红帽企业 7.5。 -R。 - RStudio 服务器。 - 管道工 API 将 R 函数公开为 Web 服务端点。 - 客户端是 Excel VBA.
问题: - 具有不同类型列的数据 table,包括双精度、整数和字符串数据。 - 就在 R 端点函数发送响应(table)之前,当我检查数据 table 中的双精度数据时,所有条目的长度都在 6 到 10 decimal-place 之间。 - 一旦 table 以 JSON 格式到达客户端,99% 的双列将四舍五入为 4 decimal-place 长。
知道可能是什么问题 - 为什么双打会四舍五入,四舍五入发生在什么地方,我该如何防止这种情况? - 我尝试了不同的请求 header 设置,但没有成功。 - 我试图将受影响的双 column/s 作为 vector/s 或 list/s 发送,但我得到相同的 "enforced" 舍入。
提前致谢
这没有很好的记录,但事实证明这是在 jsonlite::toJSON
序列化程序 (digits = 4
) 中使用默认值的结果。这里有一些细节:
https://www.rplumber.io/articles/rendering-output.html
我看不出如何从参数化中将参数传递给它,但这里有一个解决方法:
library(plumber)
#* @apiTitle A Test API
#* Run a simple function
#* @get /
function(req, res) {
x <- rnorm(1)
res$body <- jsonlite::toJSON(x, digits = NA)
res
}
# plumb("plumber_1.R")$run(port = 5762)
# Save this file as e.g. "plumber_1.R" and run the commented line
那么你应该能够得到这样的回复:
library(httr)
y <- GET("http://127.0.0.1:5762/")
content(y, as = "text")
[1] "[-0.982448323838634]"
因此,无论函数的结果是什么,使用 jsonlite::toJSON(..., digits = NA)
对其进行预序列化,并将其直接存储在响应主体中,然后 return 响应对象。
事实证明有一种“正确”的方法可以做到这一点,我通过将其归档为 GitHub 问题 https://github.com/trestletech/plumber/issues/403 发现了这一点。但是,看起来这个版本还没有在 CRAN 上,所以您可以同时使用上面的修复程序。
在您的 API 定义中,像这样指定序列化程序:
#' @serializer json list(digits = 12)
或 json 特别是
#' @json(digits = 12)