Ответ R POST с использованием Plumber API преобразует двойные 10 десятичных знаков (желаемая точность) в двойные 4 десятичных знака на стороне клиента - PullRequest
2 голосов
/ 21 марта 2019

Платформа: - Экземпляр AWS с 16 ядрами и 128 ГБ ОЗУ.- Redhat Enterprise 7.5.- R. - RStudio Server.- Plumber API предоставляет функции R в качестве конечных точек веб-службы.- На стороне клиента Excel VBA.

Проблема: - Таблица данных с различными типами столбцов, включая данные типа double, integer и strings.- Прямо перед тем, как функция конечной точки R отправляет ответ (таблицу), и когда я проверяю двойные данные в таблице данных, все записи имеют длину от 6 до 10 знаков после запятой.- Как только таблица поступает в формате JSON на стороне клиента, 99% двойных столбцов округляются до 4 десятичных знаков.

Любая идея, в чем может быть проблема - почему двойники округляютсяи где происходит округление и как я могу предотвратить это?- Я пробовал разные настройки заголовка запроса, и он не работал- Я пытался отправить затронутые двойные столбцы в виде вектора / ов или списков / списков, но получаю такое же «принудительное» округление.

Заранее спасибо

1 Ответ

2 голосов
/ 21 марта 2019

Это было не очень хорошо задокументировано, но оказалось, что это результат использования значений по умолчанию в сериализаторе jsonlite::toJSON (digits = 4). Здесь есть некоторые детали:

https://www.rplumber.io/docs/rendering-and-output.html#rendering-and-output

Я не вижу, как передать аргумент в вашу параметризацию, но вот обходной путь:

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), и сохраните его непосредственно в теле ответа, а затем верните объект ответа.


Оказывается, есть "правильный" способ сделать это, который я обнаружил, заполнив это как проблему GitHub https://github.com/trestletech/plumber/issues/403. Однако, похоже, что эта версия еще не на CRAN, так что вы тем временем можете использовать вышеуказанное исправление.

В своем определении API укажите сериализатор следующим образом:

#' @serializer json list(digits = 12)

или для JSON конкретно

#' @json(digits = 12)

...