2012-06-20 45 views
4

我有一個包含數字列表的文件(自己製作:for x in $(seq 10000); do echo $x; done > file)。現在R從/ dev/stdin跳過行

$> R -q -e "x <- read.csv('file', header=F); summary(x);" 

> x <- read.csv('file', header=F); summary(x); 
     V1  
Min. : 1 
1st Qu.: 2501 
Median : 5000 
Mean : 5000 
3rd Qu.: 7500 
Max. :10000 

,人們可能預期cat荷蘭國際集團的文件,並從/dev/stdin閱讀具有相同的輸出,但它並不:

$> cat file | R -q -e "x <- read.csv('/dev/stdin', header=F); summary(x);" 
> x <- read.csv('/dev/stdin', header=F); summary(x); 
     V1  
Min. : 1 
1st Qu.: 3281 
Median : 5520 
Mean : 5520 
3rd Qu.: 7760 
Max. :10000 

使用table(x)表明,一堆線被跳過:

1 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 
    1  1  1  1  1  1  1  1  1  1  1  1  1 
1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 
    1  1  1  1  1  1  1  1  1  1  1  1  1 
... 

它看起來像R做了一件有趣的事,stdin,因爲這個Python將正確地打印所有行文件:

cat file | python -c 'with open("/dev/stdin") as f: print f.read()' 

This question似乎有關,但它更多的是在跳過一個畸形的CSV文件中的行,而我的投入僅僅是一個數字的列表。

+2

如果使用'stdin'而不是'/ dev/stdin',問題就會消失。 –

+0

@VincentZoonekynd這確實很有趣!任何想法爲什麼,你使用的是哪個操作系統? (linux,unix,達爾文,cygwin) –

+0

@CarlWitthoft:我不知道它爲什麼會發生。我首先想到輸入被緩衝,只有第一個緩衝區被讀取,但是如果我增加文件的大小,就會讀取更多的數據。由於'stdin'被R識別,它可能會干擾'/ dev/stdin'的某種方式,並且會悄悄地竊取一些行。我在Linux上。 –

回答

3

head --bytes=4K file | tail -n 3

產生這樣的:

1039 
1040 
104 

這表明是R上創建的/ dev /標準輸入的輸入緩衝器大小的4KB,和初始化期間填充。當你的R代碼裏面,然後讀取的/ dev /標準輸入,它開始在文件中在這一點上:

1 
1042 
1043 
... 

事實上,如果在文件中,你通過1043更換線1041,你會得到「3」的而不是「1」在table(x)

3 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 
1  1  1  1  1  1  1  1  1  1  1  1  1 
... 

table(x)第一1實際上是1041最後一位。文件的第一個4KB已被吃掉。