【问题标题】:Extracting columns from text file从文本文件中提取列
【发布时间】:2015-08-25 02:53:39
【问题描述】:

我将一个文本文件 (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 内容的示例如下: 微软电视 | | | | | | | | 微软电视 | | | | | | | | | | | | | | | | | | | |

COL2 内容将是: 多电视 多电视 | | | | | | > DP | | | | | | | | | | | | DP | | | | | |

【问题讨论】:

  • 请说明您最终希望如何在数据框/表中表示输入。
  • 请将tree.txt 的前20 行左右粘贴到单独的块中,用于测试数据。所以你的第一个数据行是"MSTV","","&lt;=","0.4" 或者在整个数据框的 [0,1] 元素中真的有一个MLTV?
  • 而且仅仅看一下,每一行实际上只有 4 个元素,并且可能还有一个索引来显示它在树中的缩进。您的内部数据结构需要 8 宽吗?即使这样,您也会遇到困难,因为您的某些行长于 8,例如,DL
  • 正如@TimBiegeleisen 建议的那样,您想要的输出尚不清楚。
  • 附上的例子是JWEKA的J48的输出。它采用“原样”格式。最后,我需要的是提取每列中的单词(变量),并在下一步中提取它们的相关值(即 MSTV 0.4)。在第一阶段,我只需要像 EXCEL 那样将 txt 分成列(只需将其加载到 excel 中,然后您就可以看到所需的结果)。

标签: r read.table


【解决方案1】:

试试这个:

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 个空间。在 R 之外可能有一种更有效的方法来执行此操作,但这还不错。一般来说,我只是让文件对 R 可读。

您的文件看起来像一个固定宽度的文件,所以我使用 read.fwf,并使用 textConnection() 将函数指向已清理的输出。

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

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)

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

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

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

请记住,因为您希望每个新字符都有一个空格,所以我使用空格作为分隔符。但是因为这是一个固定宽度的文件,所以有些列是完全空白的,我将使用

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多