管道stdin到R

WYi*_*WYi 26 shell r pipe

我无法将stdin传递给R脚本.

这是我的玩具脚本test.R:

#!/usr/bin/env Rscript
while(length(line <- readLines('stdin', n=1, warn=FALSE)) > 0) {
  write(line, stderr())
  # process line
}
Run Code Online (Sandbox Code Playgroud)

我想通过每一行并做一些处理.这是我的输入文件名input:

aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
ffffff
Run Code Online (Sandbox Code Playgroud)

如果我做

cat input | test.R
Run Code Online (Sandbox Code Playgroud)

我只得到:

aaaaaa
Run Code Online (Sandbox Code Playgroud)

有什么我错过的吗?

Vin*_*ynd 43

如果您明确打开stdin连接,则不会发生这种情况.

#!/usr/bin/env Rscript
f <- file("stdin")
open(f)
while(length(line <- readLines(f,n=1)) > 0) {
  write(line, stderr())
  # process line
}
Run Code Online (Sandbox Code Playgroud)

  • 对于喜欢`=`而不是`<-`的人(像我这样)的提示:`<-`*不能被'=`替换为`=`(行< - readLines(f,n = 1)` . (5认同)
  • 我们到底需要关闭文件吗? (3认同)
  • 如果您希望 R 执行更典型的“unix-y”操作并等待来自 stdin 的输入(因此答案中的代码的行为类似于不带参数运行 `cat`),那么您需要使用 `open(f,阻塞=真)`。 (2认同)

Dir*_*tel 13

我和杰夫写了一篇小说来做这件事(以及其他一些事情).由于利特勒,我从来不认为密切关注RSCRIPT -但这应该在原则上的工作就好了.

这是我们早期的一个例子,使用来自/bin/ls(和快速过滤器awk)的输出来总结文件大小:

edd@max:~/svn/littler/examples$ ls -l /boot/ | \
                                    awk '!/^total/ {print $5}' | ./fsizes.r 
    Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
      24   130300   730700  3336000  4527000 14670000 

  The decimal point is 6 digit(s) to the right of the |

   0 | 0000000000000011111111122777777777
   2 | 777777777
   4 | 555577777
   6 | 
   8 | 
  10 | 
  12 | 5
  14 | 24466677

edd@max:~/svn/littler/examples$ 
Run Code Online (Sandbox Code Playgroud)

这里的脚本fsizes.r只有三行:

edd@max:~/svn/littler/examples$ cat fsizes.r 
#!/usr/bin/r -i

fsizes <- as.integer(readLines())
print(summary(fsizes))
stem(fsizes)
edd@max:~/svn/littler/examples$ 
Run Code Online (Sandbox Code Playgroud)


mmo*_*oya 5

这是我发现的最简单的(假设是数字输入):

x <- scan(file("stdin")
Run Code Online (Sandbox Code Playgroud)

你可以测试它:

$ echo -e "1\n2\n3" | R -s -e 'x <- scan(file("stdin")); summary(x)'
Read 3 items
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
    1.0     1.5     2.0     2.0     2.5     3.0 
Run Code Online (Sandbox Code Playgroud)