我有一个具有相同结构的多个xml文件的列表。其中一些有结构错误,因此无法读取,我无法手动控制它们,因为文件太多。我知道我需要暗示try或trycatch函数,我试图理解它们但我不理解如何在我的情况下使用它们。为了使示例简单,我只想将它们全部转换为csv。
library(XML)
k <- 1
Initial.files<- list.files("/My/Initial/Folder")
for(i in initial.files){
data<-dataTable(xmlToDataFrame(xmlParse(i)))
write.csv(data, file = paste("data",(k)".csv"))
k <- k+1
}
我得到的错误通常如下:
Start tag expected, '<' not found
Error in xmlToDataFrame(xmlParse(i)) :
error in evaluation the argument 'doc' in selecting a method for function 'xmlToDataFrame': Error 1: Start tag expected, '<' not found
要处理我的问题,我必须重写我的第5行代码(我知道这是错的):
data<- if(try(dataTable(xmlToDataFrame(xmlParse(i)))!= "try-error")
else{ haven't looked close to this because i didn't got that far...}...
我希望它能够读取这些文件并给我一个无法读取的文件路径列表。
xml文件的结构如下所示:
<ROWSET>
<ROW>
<line1>asdf</line1>
<line2>ghjk</line2>
</ROW>
</ROWSET>
答案 0 :(得分:4)
以下是tryCatch
的示例。当然,您可以将read.table
替换为您的功能,它仍然可以正常工作。
第一个会捕获任何错误,只返回有错误的文件路径(我创建了两个测试文件 - 一个可以被read.table
读取而另一个会抱怨)
f <- function(path = "~/desktop/test", ...) {
lf <- list.files(path = path, ...)
l <- lapply(lf, function(x) {
tryCatch(read.table(x, header = TRUE),
error = function(e) x)
})
setNames(l, basename(lf))
}
f(full.names = TRUE)
# $cool_test.txt
# cool test file
# 1 1 2 3
#
# $notcool_test.txt
# [1] "/Users/rawr/desktop/test/notcool_test.txt"
tryCatch
功能更强大,可以为您节省大量时间
如果您希望以不同方式处理特定文本的错误和/或警告,则可以grep
。例如,在这里,如果我试图读取的文件不存在,我想要一条消息。我想要存在的文件路径但由于某种原因无法读取。
f2 <- function(path = "~/desktop/test", ..., lf) {
lf <- if (!missing(lf)) lf else list.files(path = path, ...)
l <- lapply(lf, function(x) {
tryCatch(read.table(x, header = TRUE),
warning = function(w) if (grepl('No such file', w)) {
sprintf('%s does not exist', x)
} else sprintf('Some other warning for %s', x),
error = function(e) if (grepl('Error in scan', e)) {
message(sprintf('Check format of %s', x))
x
} else message(sprintf('Some other error for %s', x)))
})
setNames(l, basename(lf))
}
我添加了一个新参数,因此我可以传递一个文件路径列表,以显示它如何处理不存在的文件:
lf <- c("/Users/rawr/desktop/test/cool_test.txt",
"/Users/rawr/desktop/test/notcool_test.txt",
"/Users/rawr/desktop/test/file_does_not_exist.txt")
(out <- f2(lf = lf))
# Check format of /Users/rawr/desktop/test/notcool_test.txt
# $cool_test.txt
# cool test file
# 1 1 2 3
#
# $notcool_test.txt
# [1] "/Users/rawr/desktop/test/notcool_test.txt"
#
# $file_does_not_exist.txt
# [1] "/Users/rawr/desktop/test/file_does_not_exist.txt does not exist"
现在您有一个可以包含数据框,文件路径或其他消息的列表。您可以过滤掉数据框并以多种方式编写它们,这里有两个:
lapply(Filter(is.data.frame, out), function(x) do stuff)
for (ii in out)
if (is.data.frame(ii)) write.csv(ii) else print('not a data frame')
答案 1 :(得分:1)
首先,您要在程序中加入xml 的读取和写入 。如果要调试则不好:继续一步一步。
您可以使用robustify功能检查出现问题的时间:
robustify<-function(f,silent=T)
{
is.error <- function(x) inherits(x, "try-error")
function(...)
{
x =try(f(...),silent=silent)
if(is.error(x))
return(NA)
x
}
}
robustParsing = robustify(xmlParse)
library(XML)
lst = lapply(list.files("/My/Initial/Folder"), robustParsing )
NA
中lst
的结果会显示哪个文件失败。