2013-04-03 85 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