R sprintf最大输入长度

时间:2015-09-30 09:26:05

标签: r replace

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)。

1 个答案:

答案 0 :(得分:1)

我编写了一个小函数,将fmt参数切割成较小的部分,查找与%...表达式关联的变量,然后为每个部分调用sprintfmatch.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 );"
  

也许可以使用正则表达式来检测%...并找到合适的切割点。