在 R 的 read.delim 中获取额外的 NA 列

Getting additional NA column in read.delim in R

我正在读取 R 格式的文本文件(来自终端)

hmi$ head -2 output_perl_hmi.txt 
1   CG10619-RB  tup 18864094    18864523    rev GFP_RNAi3_R1    0.870707220482784   
1   CG11050-RC  CG11050 6613278 6612484 rev GFP_RNAi3_R1    0.999267733859066   

但是当我使用 read.delim 在 R 中阅读此内容时,它会在末尾添加一个额外的 NA 列。我可以只删除该列,但我想知道为什么要创建该附加列以及在实际读取文件时如何避免这种情况。

> d=read.delim("output_perl_hmi.txt", header=F)
> colnames(d) <-c("COUNT", "flybasename", "GENENAME", "START", "END", "TYPE","SAMPLE", "posterior_probability")
> head(d)
  COUNT flybasename GENENAME    START      END TYPE       SAMPLE posterior_probability NA
1     1  CG10619-RB      tup 18864094 18864523  rev GFP_RNAi3_R1             0.8707072 NA
2     1  CG11050-RC  CG11050  6613278  6612484  rev GFP_RNAi3_R1             0.9992677 NA

首先,我必须推断您的输入文件是由制表符分隔的,即使您没有指定它,因为 read.delim() 默认为 sep='\t'

其次,我强烈怀疑您在数据末尾多了一列 NA 的原因是您在输入文件的每一行末尾都有一个尾随制表符。这导致 read.delim() 认为尾随制表符后有一列,并将其解析为 NA,因为那里什么也没有。

下面我演示一下。我创建了两个文件,file1.txtfile2.txt。前者包含您将其粘贴到问题中时的确切输入文件,前提是 (1) 它使用制表符分隔符,并且 (2) 每行只有一个尾随制表符。后者是相同的,但没有尾随制表符。

为了澄清空格,在我的 cat 调用中,我传递了 -vet,它将制表符显示为 ^I,将 EOL 显示为 $。通常这不足以完全消除数据歧义,但由于我们知道您的输入文件没有抑扬符或美元,因此在这种情况下它会很明确。

system('cat -vet file1.txt;');
## 1^ICG10619-RB^Itup^I18864094^I18864523^Irev^IGFP_RNAi3_R1^I0.870707220482784^I$
## 1^ICG11050-RC^ICG11050^I6613278^I6612484^Irev^IGFP_RNAi3_R1^I0.999267733859066^I$
d <- read.delim('file1.txt', header=F );
d;
##   V1         V2      V3       V4       V5  V6           V7        V8 V9
## 1  1 CG10619-RB     tup 18864094 18864523 rev GFP_RNAi3_R1 0.8707072 NA
## 2  1 CG11050-RC CG11050  6613278  6612484 rev GFP_RNAi3_R1 0.9992677 NA
system('cat -vet file2.txt;');
## 1^ICG10619-RB^Itup^I18864094^I18864523^Irev^IGFP_RNAi3_R1^I0.870707220482784$
## 1^ICG11050-RC^ICG11050^I6613278^I6612484^Irev^IGFP_RNAi3_R1^I0.999267733859066$
d <- read.delim('file2.txt', header=F );
d;
##   V1         V2      V3       V4       V5  V6           V7        V8
## 1  1 CG10619-RB     tup 18864094 18864523 rev GFP_RNAi3_R1 0.8707072
## 2  1 CG11050-RC CG11050  6613278  6612484 rev GFP_RNAi3_R1 0.9992677

因此,一个好的解决方案是在将输入文件读入 R 之前从输入文件中去除尾随空格。(注意:我研究了使用 strip.whitecolClassescol.names read.table() 的参数(从 read.delim() 调用,将 ... 传递给它)通过自动去除空格或忽略额外的列来解决问题,但我没有尝试任何工作。)

此外,对于一般兴趣和知识,如果您有多个尾随制表符,每个制表符都会被 read.delim() 用作分隔符,因此您会在返回的 data.frame 中收到相应的列对于每个这样的标签:

system('cat -vet file3.txt;');
## 1^ICG10619-RB^Itup^I18864094^I18864523^Irev^IGFP_RNAi3_R1^I0.870707220482784^I^I$
## 1^ICG11050-RC^ICG11050^I6613278^I6612484^Irev^IGFP_RNAi3_R1^I0.999267733859066^I^I$
d <- read.delim('file3.txt', header=F );
d;
##   V1         V2      V3       V4       V5  V6           V7        V8 V9 V10
## 1  1 CG10619-RB     tup 18864094 18864523 rev GFP_RNAi3_R1 0.8707072 NA  NA
## 2  1 CG11050-RC CG11050  6613278  6612484 rev GFP_RNAi3_R1 0.9992677 NA  NA

为了真正完整,我刚刚测试了 read.delim(),看看如果输入行包含不一致数量的分隔符,它会做什么。它似乎尊重 "widest" 输入行,这意味着返回的 data.frame 将包含尽可能多的列,以覆盖输入文件中分隔最多的行。所有短线都将在其最右侧的单元格中显示 NA,但该线未包含该单元格。