2013-04-03 46 views
7

我给看看周围什么困扰我,我才发现这一点: Do some programs not accept process substitution for input files?进程替换

这部分帮助,但我真的想了解完整的故事。 我注意到当我使用进程替换时,一些R脚本给出了不同的(即错误的)结果。

我试图与一个测试用例以查明问题:

这个脚本:

#!/usr/bin/Rscript 

args <- commandArgs(TRUE) 
file <-args[1] 
cat(file) 
cat("\n") 
data <- read.table(file, header=F) 
cat(mean(data$V1)) 
cat("\n") 

以这种方式生成的输入文件:

$ for i in `seq 1 10`; do echo $i >> p; done 
$ for i in `seq 1 500`; do cat p >> test; done 

使我这个:

$ ./mean.R test 
test 
5.5 

$ ./mean.R <(cat test) 
/dev/fd/63 
5.501476 

进一步的测试表明,一些线路丢失了......但我想明白为什么。 read.table(扫描结果是否相同)使用seek?

诗篇。 具有较小测试文件中报告(100)的错误:

$./mean.R <(cat test3) 
/dev/fd/63 
Error in read.table(file, header = F) : no lines available in input 
Execution halted 

添加#1:与使用扫描结果是相同的一个修改后的脚本。

+1

'read.table'可能会窥探文件以确定列格式,然后在回溯到开始时失败。 (只是疯狂的猜测)如果你的R脚本中有'cat(head(data $ V1))',会发生什么? – krlmlr

+0

在进程重定向的情况下给出'2 3 4 5 6 7',而不是'1 2 3 4 5 6'。打印整个数据框给5001条没有它(正确)的行,在另一个情况下为3050条。我也认为寻求可能是问题,但是......它不应该报告错误而不是继续使用部分数据吗? – vodka

+0

在文件中上下移动肯定是问题:https://stat.ethz.ch/pipermail/r-help/2007-September/141769.html但我仍然认为应该报告一个错误,也许我会填写一个错误。我仍然需要调查扫描是否也发生了同样的情况(这给了我和read.table一样的错误结果)。 – vodka

回答

8

我写了这个通用功能打开我自己的脚本文件的连接:

OpenRead <- function(arg) { 

    if (arg %in% c("-", "/dev/stdin")) { 
     file("stdin", open = "r") 
    } else if (grepl("^/dev/fd/", arg)) { 
     fifo(arg, open = "r") 
    } else { 
     file(arg, open = "r") 
    } 
} 

在代码中,替换filefile <- OpenRead(file),它应该处理所有的如下:

./mean.R test 
./mean.R <(cat test) 
cat test | ./mean.R - 
cat test | ./foo.R /dev/stdin 
+0

是的,这是有效的(事实上,我注意到使用“/ dev/stdin”的问题,并在前一段时间切换到“stdin”)。我仍然认为这可能会被视为R中的一个错误,尽管... – vodka