【问题标题】:How to read whitespace delimited strings until EOF in R如何在 R 中读取空格分隔的字符串直到 EOF
【发布时间】:2023-09-19 02:03:01
【问题描述】:

我是 R 新手,目前在遇到 EOF 之前无法读取一系列字符串。我不仅不知道如何检测 EOF,而且我也不知道如何读取由空格分隔的单个字符串,这在我迄今为止见过的任何其他语言中都是微不足道的。在 C 语言中,我会这样做:

while (scanf("%s", s) == 1) { /* do something with s */ }

如果可能,我更喜欢不需要提前知道最大字符串长度的解决方案。

有什么想法吗?

编辑:我正在寻找不将所有输入存储到内存中的解决方案,而是与上面的 C 代码等效或至少相似的解决方案。

【问题讨论】:

  • readLines 默认读取文本直到文件结束
  • 我尝试过扫描,但似乎它会一直读取直到遇到 EOF。我想一一阅读字符串,因为我正在阅读数百万个字符串(我更新了问题)。

标签: string r input eof


【解决方案1】:

这是一种一次读取一个项目的方法...它使用scan 有一个nmax 参数(以及nnlines - 它实际上有点混乱!)这一事实。

# First create a sample file to read from...
writeLines(c("Hello world", "and now", "Goodbye"), "foo.txt")

# Use a file connection to read from...
f <- file("foo.txt", "r")

i <- 0L
repeat {
   s <- scan(f, "", nmax=1, quiet=TRUE)
   if (length(s) == 0) break
   i <- i + 1L
   cat("Read item #", i, ": ", s, "\n", sep="")
}
close(f)

当 scan 遇到 EOF 时,它会返回一个长度为零的向量。因此,一种更晦涩但类似于 C 的方式是:

while (length(s <- scan(f, "", nmax=1, quiet=TRUE))) {
   i <- i + 1L
   cat("Read item #", i, ": ", s, "\n", sep="")
}

无论如何,输出将是:

Read item #1: Hello
Read item #2: world
Read item #3: and
Read item #4: now
Read item #5: Goodbye

最后,如果您可以矢量化您对字符串所做的操作,您可能应该尝试一次读取一堆字符串 - 只需将 nmax 更改为,例如,10000

【讨论】:

    【解决方案2】:
    > txt <- "This is an example"  # could be from a file but will use textConnection()
    > read.table(textConnection(txt))
        V1 V2 V3      V4
    1 This is an example
    

    read.table是用scan实现的,看代码就知道专家是怎么做的了。

    【讨论】:

    • 但这会将所有内容加载到内存中,对吧?我需要以一种节省内存的方式来完成,就像 C 版本一样。我更新了原帖。
    • 将数据加载到内存中是“R方式”。如果您想要编译语言,请使用编译语言。
    • @DWin - 我认为一次阅读一个项目然后对其进行大量计算仍然很适合 R 范式?
    • 你说得对。文件连接也应该适用于任何基于 scan 的解决方案。
    最近更新 更多