Plumber API返回CSV时部分字符串被额外引号包裹的问题排查
Plumber返回CSV时特定字符串被额外引号包裹的排查与解决
问题复现
使用R的plumber库开发API返回CSV格式数据时,发现NASH、NAS这类字符串会被自动添加额外引号,但其他字符串(如LAFC、PUNI)正常;将这些字符串替换为NA、NSH则无此问题。相关代码如下:
runapi.R
# !/usr/bin/env Rscript library(plumber) pr <- plumber::plumb("endpoints.R") pr$run(host = "0.0.0.0", port = 8004)
endpoints.R
#* @param season The season we want #* @get /preseason-preds #* @serializer csv list(type="text/plain; charset=UTF-8") preseasonPreds <- function(res, season = 2023) { api_df <- readr::read_csv(file = 'data/our_csv.csv') return(api_df) }
data/our_csv.csv
TeamID,FeedID NASH,148048 LAFC,147671 PUNI,275
调用接口后,输出的CSV中NASH会被引号包裹,其余字符串正常。
原因分析
这个问题源于plumber默认使用readr::write_csv进行CSV序列化,而readr的写入逻辑会对疑似缺失值标记的字符串自动添加引号,防止后续解析工具将其误识别为缺失值(R默认缺失值为NA)。NAS、NASH以NA开头,触发了readr的这个特殊处理逻辑。
解决方法
方法1:自定义CSV序列化,明确缺失值标记
通过手动调用readr::format_csv并指定na参数,仅将空字符串视为缺失值,避免readr误判NAS/NASH:
修改endpoints.R如下:
#* @param season The season we want #* @get /preseason-preds preseasonPreds <- function(res, season = 2023) { api_df <- readr::read_csv(file = 'data/our_csv.csv') # 设置响应头 res$setHeader("Content-Type", "text/plain; charset=UTF-8") # 自定义序列化,指定仅空字符串为缺失值 return(readr::format_csv(api_df, na = "")) }
方法2:使用base R的CSV写入逻辑
如果不需要readr的特殊处理,可改用base R的write.table生成CSV,该工具不会对开头为NA的字符串做特殊处理:
修改endpoints.R如下:
#* @param season The season we want #* @get /preseason-preds preseasonPreds <- function(res, season = 2023) { api_df <- readr::read_csv(file = 'data/our_csv.csv') # 设置响应头 res$setHeader("Content-Type", "text/plain; charset=UTF-8") # 使用base R生成CSV文本,关闭全局引号(若需保留含特殊字符字符串的引号,可将quote设为TRUE) csv_output <- capture.output( write.table(api_df, sep = ",", row.names = FALSE, quote = FALSE, na = ""), type = "output" ) return(paste(csv_output, collapse = "\n")) }
验证效果
修改后重新启动API,调用接口返回的CSV中NASH、NAS将不再被额外引号包裹,输出与原始CSV一致。
内容的提问来源于stack exchange,提问作者Canovice
相关产品推荐
相关产品推荐

