从R中的stdin读取时的奇怪行为

时间:2014-07-15 13:13:01

标签: r stdin

我试图了解在执行Rscript时从STDIN读取时会发生什么。

首先,我有一个文件,其中包含我想要读入R的数据:

root@CentOS64 testscripts # cat rdata
5 7

这是我的第一个Rscript,

a <- scan(file="stdin", what=integer(0), n=1);
b <- scan(file="stdin", what=integer(0), n=1);

导致此行为:

root@CentOS64 testscripts # Rscript ../rscripts/ttest.r < rdata
Read 1 item
Read 0 items
root@CentOS64 testscripts # cat rdata | Rscript ../rscripts/ttest.r
Read 1 item
Read 0 items

此时我已经感到困惑,为什么只读取一个值。我一直试图找到有关scan函数的更多信息,但我找不到任何可以解释这一点的信息。

如果我将Rscript更改为以下内容,

sin <- file("/dev/stdin");
a <- scan(sin, what=integer(0), n=1);
b <- scan(sin, what=integer(0), n=1);

我得到了这个结果:

root@CentOS64 testscripts # Rscript ../rscripts/ttest.r < rdata
Read 1 item
Read 1 item
root@CentOS64 testscripts # cat rdata | Rscript ../rscripts/ttest.r
Read 0 items
Read 0 items

这让我更加困惑,结果应该是等价的。最后,如果我尝试这个命令:

root@CentOS64 testscripts # cat rdata > tmp; Rscript ../rscripts/ttest.r < tmp
Read 1 item
Read 1 item

我得到了预期的行为。有人可以向我解释发生了什么事吗?为什么R不能以流式方式从管道读取数据?

1 个答案:

答案 0 :(得分:1)

当您使用scan作为输入来调用"stdin"时,它会立即读取整个标准输入,即使您只是将其限制为一个字符。你第二次打电话,没有任何东西,所以它什么都不返回。

如果要“一次一个”读取标准输入,则可以使用“读取”模式设置的文件连接。如果您使用ttest.r脚本:

con=file("stdin", "r")
scan(file=con, what=integer(0), n=1)
scan(file=con, what=integer(0), n=1)

然后你从你的shell打来电话:

Rscript ttest.r < rdata
# Read 1 item
# [1] 5
# Read 1 item
# [1] 7     

我有点困惑,为什么你不会得到我尝试用另一种方式管道的东西:

cat rdata | Rscript ttest.r
# Read 1 item
# [1] 5
# Read 1 item
# [1] 7