2012-06-20 28 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已被吃掉。