2013-04-03 12 views
7

ho dato un'occhiata in giro su ciò che mi lascia perplesso e ho trovato questo solo: Do some programs not accept process substitution for input files?processo di sostituzione

che è parzialmente aiutando, ma mi piacerebbe davvero capire la storia completa. Ho notato che alcuni dei miei script R danno risultati diversi (cioè errati) quando utilizzo la sostituzione del processo.

ho cercato di individuare il problema con un banco di prova:

Questo script:

#!/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") 

con un file di input generato in questo modo:

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

mi porta a questo:

$ ./mean.R test 
test 
5.5 

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

Ulteriori test rivelano che alcune linee sono perse ... ma mi piacerebbe capire perché. Read.table (la scansione dà gli stessi risultati) usa seek?

Ps. con un file di prova più piccolo viene riportato (100) un errore:

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

Aggiungi # 1: con uno script modificato che utilizza la scansione i risultati sono gli stessi.

+1

'read.table' potrebbe dare un'occhiata al file per determinare i formati delle colonne e quindi fallire quando si cerca di tornare all'inizio. (Solo un'ipotesi.) Cosa succede se tu 'cat (testa (dati $ V1))' nel tuo script R? – krlmlr

+0

con il reindirizzamento del processo restituisce "2 3 4 5 6 7', senza" 1 2 3 4 5 6 ". La stampa di tutti i frame di dati fornisce 5001 linee senza di essa (correttamente) e 3050 nell'altro caso. Penso anche che la ricerca potrebbe essere il problema ma ... non dovrebbe riportare un errore invece di andare avanti con dati parziali? – vodka

+0

andare su e giù nel file è sicuramente il problema: https://stat.ethz.ch/pipermail/r-help/2007-Settembre/141769.html ma credo ancora che un errore dovrebbe essere segnalato e forse lo farò riempire un bug Devo ancora indagare se lo stesso accade con la scansione (che mi dà gli stessi risultati errati di read.table). – vodka

risposta

8

Ho scritto questa funzione di uso generale per l'apertura di un collegamento file in mio script:

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") 
    } 
} 

Nel codice, sostituire file con file <- OpenRead(file) e dovrebbe gestire tutte quelle qui sotto:

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

Sì, funziona (e in effetti ho notato problemi con "/ dev/stdin" e passato a "stdin" qualche tempo fa). Credo comunque che questo potrebbe essere visto come un bug in R anche se ... – vodka

Problemi correlati