【问题标题】:R sprintf maximal input lengthR sprintf 最大输入长度
【发布时间】:2015-12-28 00:39:54
【问题描述】:

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 非常适合,但我正在使用的输入脚本之一太长了。我需要替换多个不同的参数,并且参数具有不同的格式(字符串、双精度、浮点)。要替换的值位于输入文件的不同部分,因此我需要按给定顺序搜索和替换它们。我知道 this approach 到参数化查询,但需要使用不同的库 (RPostgreSQL)。

【问题讨论】:

  • 您有时可以将sprintf 替换为paste 等函数。你不能举一个具体的最小例子吗?
  • 进一步参数化你的格式字符串?
  • @James 我不明白你的意思..?
  • 例如select * from long_table_name where ...变成select * from %s where ...
  • @James 这个例子很像我现实生活中的问题,有字符串和数字要替换,大多数情况下替换值是短字符串(比如

标签: r replace


【解决方案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 );"

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

【讨论】:

    猜你喜欢
    • 2012-06-02
    • 2011-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 2018-03-31
    • 2020-01-05
    • 2014-10-17
    相关资源
    最近更新 更多