从文本文件中提取列

Extracting columns from text file

我将一个文本文件 (tree.txt) 加载到 R,其中包含以下内容(从 JWEKA - J4​​8 命令复制粘贴)。 我使用以下命令加载文本文件:

data3 <-read.table (file.choose(), header = FALSE,sep = ",")

我想将每一列插入到一个单独的变量中,其名称类似于以下格式 COL1、COL2 ... COL8(在本例中,因为我们有 8 列)。如果您将其加载到 EXCEL 并使用定界分隔,则每一行将被分隔成一列(这是必需的结果)。 在此示例中,每个 COLn 将包含树的相关字符。 如何在忽略文件的页眉和页脚内容的情况下自动将文本文件分隔并插入到这些列中?

文本文件内容如下:

[[1]]                                                               
J48 pruned  tree                                                        
------------------                                                              

MSTV    <=  0.4                                                     
|   MLTV    <=  4.1:    3   -2                                          
|   MLTV    >   4.1                                                 
|   |   ASTV    <=  79                                              
|   |   |   b   <=  1383:00:00  2   -18                                 
|   |   |   b   >   1383                                            
|   |   |   |   UC  <=  05:00   1   -2                              
|   |   |   |   UC  >   05:00   2   -2                              
|   |   ASTV    >   79:00:00    3   -2                                      
MSTV    >   0.4                                                     
|   DP  <=  0                                                   
|   |   ALTV    <=  09:00   1   (170.0/2.0)                                     
|   |   ALTV    >   9                                               
|   |   |   FM  <=  7                                           
|   |   |   |   LBE <=  142:00:00   1   (27.0/1.0)                              
|   |   |   |   LBE >   142                                     
|   |   |   |   |   AC  <=  2                                   
|   |   |   |   |   |   e   <=  1058:00:00  1   -5                      
|   |   |   |   |   |   e   >   1058                                
|   |   |   |   |   |   |   DL  <=  04:00   2   (9.0/1.0)                   
|   |   |   |   |   |   |   DL  >   04:00   1   -2                  
|   |   |   |   |   AC  >   02:00   1   -3                          
|   |   |   FM  >   07:00   2   -2                                  
|   DP  >   0                                                   
|   |   DP  <=  1                                               
|   |   |   UC  <=  03:00   2   (4.0/1.0)                                   
|   |   |   UC  >   3                                           
|   |   |   |   MLTV    <=  0.4:    3   -2                              
|   |   |   |   MLTV    >   0.4:    1   -8                              
|   |   DP  >   01:00   3   -8                                      

Number  of  Leaves  :   16                                              

Size    of  the tree    :   31

COL1 内容示例如下: MSTV | | | | | | | | MSTV | | | | | | | | | | | | | | | | | | | |

COL2 内容将是: MLTV MLTV | | | | | | > DP | | | | | | | | | | | | DP | | | | | |

试试这个:

cleaned.txt <- capture.output(cat(paste0(tail(head(readLines("FILE_LOCATION"), -4), -4), collapse = '\n'), sep = '\n'))
cleaned.df <- read.fwf(file = textConnection(cleaned.txt), 
                   header = FALSE, 
                   widths = rep.int(4, max(nchar(cleaned.txt)/4)),
                   strip.white= TRUE
                   )
cleaned.df <- cleaned.df[,colSums(is.na(cleaned.df))<nrow(cleaned.df)]

对于清理过程,我最终使用头部和尾部的组合来移除顶部和底部的 4 spaces。在 R 之外可能有更有效的方法来执行此操作,但这还不错。通常,我只是让文件对 R 可读。

您的文件看起来像 fixed-width 文件,所以我使用 read.fwf,并使用 textConnection() 将函数指向已清理的输出。

最后,我不确定你的数据实际上是如何构造的,但是当我从 Whosebug 复制它时,它在每一行的末尾粘贴了一堆白色space。我正在使用一些技巧来猜测文件的长度,并在此处删除无关的列

widths = rep.int(4, max(nchar(cleaned.txt)/4))
cleaned.df <- cleaned.df[,colSums(is.na(cleaned.df))<nrow(cleaned.df)]

接下来,我将按照您希望的结构化方式创建数据。

for (i in colnames(cleaned.df)) {
  assign(i, subset(cleaned.df, select=i))
  assign(i, capture.output(cat(paste0(unlist(get(i)[get(i)!=""])),sep = ' ', fill = FALSE)))
}

rm(i)
rm(cleaned.df)
rm(cleaned.txt)

它的作用是为数据框中的每一列 header 创建一个循环。

从那里它使用 assign() 将每列中的所有数据放入它自己的数据框中。在您的例子中,它们被命名为 V1 到 V15。

接下来,它结合使用 cat() 和 paste() 与 unlist() 和 capture.output() 将您的列表连接成单个字符向量,对于每个数据框,因此它们现在是字符向量,而不是数据框。

请记住,因为您希望在每个新字符处使用 space,所以我使用 space 作为分隔符。但是因为这是一个 fixed-width 文件,有些列是完全空白的,我正在使用

将其删除
get(i)[get(i)!=""]

(你的问题说你希望 COL2 是:MLTV MLTV | | | | | | > DP | | | | | | | | | | | DP | | | | | |)。

如果我们只使用get(i),输出中会有一个前导白色space。