R sprintf
已将预设的最大输入长度设置为8192字节:
sprintf(x, y)
Error in sprintf(x, y) : 'fmt' length exceeds maximal format length 8192
更长输入字符串的解决方法是什么?我在C中了解到这种情况有snprintf函数,但这似乎不适用于R,不是吗?
实施例
输入文件类似于
select *
from some_table
where a = '%s' and
b = %d and
c in (%s) and
d = %s and
e >= %0.2f
但很多更复杂,很多更长。我需要用一些值替换所有值。 sprintf
非常适合,但我正在使用的输入脚本之一太长了。我需要替换多个不同的参数,并且参数具有不同的格式(string,double,float)。要替换的值位于输入文件的不同部分,因此我需要按给定顺序搜索和替换它们。我知道this approach参数化查询,但需要使用不同的库(RPostgreSQL
)。
答案 0 :(得分:1)
我编写了一个小函数,将fmt
参数切割成较小的部分,查找与%...
表达式关联的变量,然后为每个部分调用sprintf
。 match.call
用于获取...
中隐藏的参数。 sprintf
是通过do.call
调用的,因为先验我们不知道...
中哪些进一步的参数属于当前的fmt
。
功能完全不完美。例如,到目前为止,fmt
被切成固定长度的片段。一般情况下,这不起作用,因为您必须保持%...
表达式不变。为了查看它是否有效,我将结果保留为字符串列表。
f <- function(N, fmt, ...)
{
cl <- as.list(match.call())
n <- nchar(fmt)
p <- which(unlist(strsplit(fmt,""))=="%")
result <- list()
for ( i in 0:(n%/%N))
{
start <- i*N+1
end <- min((i+1)*N,n)
fm <- substr(fmt,start,end)
k <- which(p %in% (start:end))
v <<- c(list(fm),cl[k+3])
result[[i+1]] <- do.call("sprintf", v )
}
return(result)
}
使用长度为10的碎片的小例子:
> f( 10, "xyz: %i -ää %s 3 %i %f );", 3, "+++", 12, 0.123 )
[[1]]
[1] "xyz: 3 -ä"
[[2]]
[1] "ä +++ 3 12 "
[[3]]
[1] "0.123000 );"
> paste(f( 10, "xyz: %i -ää %s 3 %i %f );", 3, "+++", 12, 0.123 ),collapse="")
[1] "xyz: 3 -ää +++ 3 12 0.123000 );"
也许可以使用正则表达式来检测%...
并找到合适的切割点。