2015-06-11 3 views
0

Я хочу прочитать мой xml в dataframe в r. Мой intial Datafile составляет 14 Гб, так моя первая попытка прочитать файл не получилось:Прочитать большой xml в Dataframe r

f=xmlParse("Final.xml") 
df=xmlToDataFrame(f) 
r=xmlRoot(f) 

Проблема заключается в том, что она всегда уходит из памяти ....

Я также видел вопрос:

How to read large (~20 GB) xml file in R?

Я пытался использовать подход от Мартина Моргана, который я сделал не 100% понял, но попытался применить к моему набору данных.

libary(XML) 
branchFunction <- function() { 
store <- new.env() 
func <- function(x, ...) { 
ns <- getNodeSet(x, path = "//Sentiment") 
value <- xmlValue(ns[[1]]) 
print(value) 
# if storing something ... 
# store[[some_key]] <- some_value 
} 
getStore <- function() { as.List(store) } 
list(ROW = func, getStore=getStore) 
} 

myfunctions <- branchFunction() 

xmlEventParse(
file = "Inputfile.xml", 
handlers = NULL, 
branches = myfunctions 
)) 

myfunctions$getStore() 

Я бы сделать это для каждого столбца в отдельности и структуры я получаю от ouptput не является полезным.

Структура из моих данных выглядит следующим образом:

<ROWSET> 
<ROW> 
    <Field1>21706</Field1> 
    <PostId>19203</PostId> 
    <ThreadId>38</ThreadId> 
    <UserId>1397</UserId> 
    <TimeStamp>1407351854</TimeStamp> 
    <Upvotes>0</Upvotes> 
    <Downvotes>0</Downvotes> 
    <Flagged>f</Flagged> 
    <Approved>t</Approved> 
    <Deleted>f</Deleted> 
    <Replies>0</Replies> 
    <ReplyTo>egergeg</ReplyTo> 
    <Content>dsfg</Content> 
<Sentiment>Neutral</Sentiment> 
</ROW> 
<ROW> 
    <Field1>217</Field1> 
    <PostId>1903</PostId> 
    <ThreadId>8</ThreadId> 
    <UserId>197</UserId> 
    <TimeStamp>1407351854</TimeStamp> 
    <Upvotes>0</Upvotes> 
    <Downvotes>0</Downvotes> 
    <Flagged>f</Flagged> 
    <Approved>t</Approved> 
    <Deleted>f</Deleted> 
    <Replies>0</Replies> 
    <ReplyTo>sdrwer</ReplyTo> 
    <Content>wer</Content> 
<Sentiment>Neutral</Sentiment> 
</ROW> 
<ROW> 
    <Field1>21306</Field1> 
    <PostId>19103</PostId> 
    <ThreadId>78</ThreadId> 
    <UserId>13497</UserId> 
    <TimeStamp>1407321854</TimeStamp> 
    <Upvotes>0</Upvotes> 
    <Downvotes>0</Downvotes> 
    <Flagged>f</Flagged> 
    <Approved>t</Approved> 
    <Deleted>f</Deleted> 
    <Replies>0</Replies> 
    <ReplyTo>tzjtj</ReplyTo> 
    <Content>rtgr</Content> 
<Sentiment>Neutral</Sentiment> 
</ROW> 
</ROWSET> 
+0

Вы должны предоставить * полный * минимальный пример вашего XML, в противном случае для других действительно сложно проверить их предлагаемое решение. – Thomas

+0

Я расширил пример xml, кажется, что часть xml вырезана, когда я разместил ее. – Carlo

ответ

1

В вашем случае, так как вы имеете дело с большими наборами данных, вы действительно должны использовать xmlEventParse опирающиеся на SAX, т.е. в Simple API для XML. Преимущество этого в сравнении с использованием xmlParse заключается в том, что вы не загрузите дерево XML в R (что может вызвать утечку памяти, если данные действительно большие ...).

У меня нет большого набора данных в руках, так что я не могу проверить в реальных условиях, но вы можете попробовать этот код:

xmlDoc <- "Final.xml" 
result <- NULL 

#function to use with xmlEventParse 
row.sax = function() { 
    ROW = function(node){ 
      children <- xmlChildren(node) 
      children[which(names(children) == "text")] <- NULL 
      result <<- rbind(result, sapply(children,xmlValue)) 
      } 
    branches <- list(ROW = ROW) 
    return(branches) 
} 

#call the xmlEventParse 
xmlEventParse(xmlDoc, handlers = list(), branches = row.sax(), 
       saxVersion = 2, trim = FALSE) 

#and here is your data.frame 
result <- as.data.frame(result, stringsAsFactors = F) 

Позвольте мне знать, как это работает!

+0

Я попытался запустить код с 4-гигабайтным набором данных. Проблема заключается в том, что xmlEventParse создает только пустой список. Он работал хорошо на небольшом наборе данных, но не смог создать Dataframe на большом наборе данных. @eblondel – Carlo

+0

xmlEventParse действительно возвращает пустой список, но вам не нужно заботиться о том, что возвращает '' xmlEventParse'' (вы можете вставить '' xmlEventParse'' с '' invisible() ''. С помощью функции '' row. sax'', мы передаем объект '' result''. Использование '' xmlEventParse'' не позволяет дублировать память, используемую в R (дерево XML + результирующий '' data.frame''). Код Я предоставил вам возможность иметь только '' data.frame''. Получаете ли вы ошибку в большом наборе данных?, чтобы узнать, могу ли я вам помочь – eblondel

+0

На маленьком xml xmlEventParse создает большую матрицу, проблема в том, что Объект, созданный с помощью xmlEventParse, создает значение NULL (пустое) вместо большой матрицы. Кроме того, нет ошибок или предупреждений, возникающих при завершении обработки xmlEventParse. Также процесс будет слишком быстрым, он должен занимать не менее 20 минут и останавливаться/заканчиваться после 5 минут. @eblondel – Carlo

Смежные вопросы