我正在尝试从文本文件中提取表格,并在此处找到了几个解决类似问题的帖子。但是,似乎没有人能够有效地解决我的问题。我找到的最有帮助的答案是我之前的一个问题:R: removing header, footer and sporadic column headings when reading csv file
示例虚拟文本文件包含:
>
>
> ###############################################################################
>
> # 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
。
我找到帖子:Extracting Data from Text Files但是,在发布的答案中,有问题的表似乎有固定的行数。在我的情况下,行数可以在1到20之间变化。另外,我更喜欢使用base R
。就我而言,我认为bottom
和表格最后一行之间的行数是一个常数(这里是4)。
我也发现帖子:How to extract data from a text file using R or PowerShell?但是,在我的情况下,列宽不固定,我不知道如何拆分字符串(或行),所以只有七列。
考虑到以上所有问题,我的问题可能是如何将对象aa
拆分成列。感谢您的任何建议或帮助。
编辑:
实际日志由超级计算机生成,最多包含90,000行。但是,日志之间的行数变化很大。这就是我使用top
和bottom
。
答案 0 :(得分: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
答案 1 :(得分: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
答案 2 :(得分:1)
你必须阅读R控制台看起来很奇怪。无论如何,您可以使用表格线以数字开头的事实,并使用^[0-9]+
之类的内容提取您的inetersting行。然后像@kohske所示的read.table
完成剩下的工作。
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
答案 3 :(得分:0)
感谢那些发布答案的人。由于实际日志文件的大小,复杂性和可变性,我认为我需要继续使用变量top
和bottom
。但是,我使用了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