0

我正在尝试从文本文件中提取表格,并在这里找到了几个解决类似问题的早期帖子。但是,似乎没有一个能有效地解决我的问题。我找到的最有用的答案是我之前的一个问题:R:在读取 csv 文件时删除页眉、页脚和零星的列标题

一个示例虚拟文本文件包含:

> 
> 
> ###############################################################################
> 
> # Display AICc Table for the models above
> 
> 
> collect.models(, adjust = FALSE)
      model npar  AICc  DeltaAICc weight  Deviance
13      P1   19    94      0.00     0.78      9
12      P2   21    94      2.64     0.20      9
10      P3   15    94      9.44     0.02      9
2       P4   11    94    619.26     0.00      9
> 
> 
> ###############################################################################
> 
> # the three lines below count the number of errors in the code above
> 
> cat("ERROR COUNT:", .error.count, "\n")
ERROR COUNT: 0 
> options(error = old.error.fun)
> rm(.error.count, old.error.fun, new.error.fun)
> 
> ##########
> 
> 

我编写了以下代码来提取所需的表:

my.data <- readLines('c:/users/mmiller21/simple R programs/dummy.log')

top    <- '> collect.models\\(, adjust = FALSE)'
bottom <- '> # the three lines below count the number of errors in the code above'

my.data <- my.data[-c(grep(bottom, my.data):length(my.data))]
my.data <- my.data[-c(1:grep(top, my.data))]
my.data <- my.data[c(1:(length(my.data)-4))]
aa      <- as.data.frame(my.data)
aa

write.table(my.data, 'c:/users/mmiller21/simple R programs/dummy.log.extraction.txt', quote=F, col.names=F, row.name=F)
my.data2 <- read.table('c:/users/mmiller21/simple R programs/dummy.log.extraction.txt', header = TRUE, row.names = c(1))
my.data2
   model npar AICc DeltaAICc weight Deviance
13    P1   19   94      0.00   0.78        9
12    P2   21   94      2.64   0.20        9
10    P3   15   94      9.44   0.02        9
2     P4   11   94    619.26   0.00        9

我宁愿避免必须先写再读my.data才能获得所需的数据帧。在该步骤之前,当前代码返回一个字符串向量my.data

[1] "      model npar  AICc  DeltaAICc weight  Deviance" "13      P1   19    94      0.00     0.78      9"   
[3] "12      P2   21    94      2.64     0.20      9"    "10      P3   15    94      9.44     0.02      9"   
[5] "2       P4   11    94    619.26     0.00      9"

有什么方法可以将上面的字符串向量转换成这样的数据框,dummy.log.extraction.txt而无需写入然后读取my.data

该行:

aa <- as.data.frame(my.data)

返回以下内容,看起来像我想要的:

#                                              my.data
# 1       model npar  AICc  DeltaAICc weight  Deviance
# 2    13      P1   19    94      0.00     0.78      9
# 3    12      P2   21    94      2.64     0.20      9
# 4    10      P3   15    94      9.44     0.02      9
# 5    2       P4   11    94    619.26     0.00      9

然而:

dim(aa)
# [1] 5 1

如果我可以分成aa几列,那么我想我将拥有我想要的东西,而不必写然后读my.data

我找到了帖子:从文本文件中提取数据 但是,在发布的答案中,有问题的表似乎有固定数量的行。在我的情况下,行数可以在 1 到 20 之间变化。另外,我更喜欢使用base R. 在我的情况下,我认为bottom表的最后一行之间的行数是一个常数(这里是 4)。

我还找到了帖子:如何使用 R 或 PowerShell 从文本文件中提取数据? 但是,在我的情况下,列宽不是固定的,我不知道如何拆分字符串(或行),所以只有七列。

鉴于以上所有情况,也许我的问题实际上是如何将对象拆分aa为列。感谢您的任何建议或帮助。

编辑:

实际日志由超级计算机生成,最多包含 90,000 行。但是,日志的行数差异很大。这就是我使用topand的原因bottom

4

4 回答 4

3

可能你的真实日志文件完全不同,而且更复杂,但有了这个,你可以read.table直接使用,你只需要使用正确的参数。

data <- read.table("c:/users/mmiller21/simple R programs/dummy.log",
                   comment.char = ">",
                   nrows = 4,
                   skip = 1,
                   header = TRUE,
                   row.names = 1)

str(data)
## 'data.frame':    4 obs. of  6 variables:
##  $ model    : Factor w/ 4 levels "P1","P2","P3",..: 1 2 3 4
##  $ npar     : int  19 21 15 11
##  $ AICc     : int  94 94 94 94
##  $ DeltaAICc: num  0 2.64 9.44 619.26
##  $ weight   : num  0.78 0.2 0.02 0
##  $ Deviance : int  9 9 9 9

data
##    model npar AICc DeltaAICc weight Deviance
## 13    P1   19   94      0.00   0.78        9
## 12    P2   21   94      2.64   0.20        9
## 10    P3   15   94      9.44   0.02        9
## 2     P4   11   94    619.26   0.00        9
于 2013-07-04T08:07:04.200 回答
3

read.table及其家人现在可以选择阅读文本:

> df <- read.table(text = paste(my.data, collapse = "\n"))
> df
   model npar AICc DeltaAICc weight Deviance
13    P1   19   94      0.00   0.78        9
12    P2   21   94      2.64   0.20        9
10    P3   15   94      9.44   0.02        9
2     P4   11   94    619.26   0.00        9
> summary(df)
 model       npar           AICc      DeltaAICc          weight         Deviance
 P1:1   Min.   :11.0   Min.   :94   Min.   :  0.00   Min.   :0.000   Min.   :9  
 P2:1   1st Qu.:14.0   1st Qu.:94   1st Qu.:  1.98   1st Qu.:0.015   1st Qu.:9  
 P3:1   Median :17.0   Median :94   Median :  6.04   Median :0.110   Median :9  
 P4:1   Mean   :16.5   Mean   :94   Mean   :157.84   Mean   :0.250   Mean   :9  
        3rd Qu.:19.5   3rd Qu.:94   3rd Qu.:161.90   3rd Qu.:0.345   3rd Qu.:9  
        Max.   :21.0   Max.   :94   Max.   :619.26   Max.   :0.780   Max.   :9  
于 2013-07-04T07:54:50.490 回答
1

您必须阅读 R 控制台,这看起来很奇怪。无论如何,您可以使用表格行以数字开头的事实,并使用类似^[0-9]+. 然后read.table就像@kohske 所展示的那样做剩下的事情。

readLines('c:/users/mmiller21/simple R programs/dummy.log')
idx <- which(grepl('^[0-9]+',ll))
idx <- c(min(idx)-1,idx)   ## header line 
read.table(text=ll[idx])   
 model npar AICc DeltaAICc weight Deviance
13    P1   19   94      0.00   0.78        9
12    P2   21   94      2.64   0.20        9
10    P3   15   94      9.44   0.02        9
2     P4   11   94    619.26   0.00        9
于 2013-07-04T08:02:47.013 回答
0

感谢那些发布答案的人。由于实际日志文件的大小、复杂性和可变性,我认为我需要继续使用变量topbottom. 但是,我使用了 dickoa 的回答元素来提出以下内容。

my.data <- readLines('c:/users/mmiller21/simple R programs/dummy.log')

top    <- '> collect.models\\(, adjust = FALSE)'
bottom <- '> # the three lines below count the number of errors in the code above'

my.data <- my.data[-c(grep(bottom, my.data):length(my.data))]
my.data <- my.data[-c(1:grep(top, my.data))]

x <- read.table(text=my.data, comment.char = ">")
x

#    model npar AICc DeltaAICc weight Deviance
# 13    P1   19   94      0.00   0.78        9
# 12    P2   21   94      2.64   0.20        9
# 10    P3   15   94      9.44   0.02        9
# 2     P4   11   94    619.26   0.00        9

这是更简单的代码:

my.data <- readLines('c:/users/mmiller21/simple R programs/dummy.log')

top    <- '> collect.models\\(, adjust = FALSE)'
bottom <- '> # the three lines below count the number of errors in the code above'

my.data  <- my.data[grep(top, my.data):grep(bottom, my.data)]

x <- read.table(text=my.data, comment.char = ">")
x
于 2013-07-04T08:59:48.700 回答