2016-09-01 20 views
1

テーマ別にいくつかのデータをXMLに変換したいと思います。だから、私はその問題の適切な解決策を見つけたので、いくつかの答えのおかげで。しかし、大きい.csvファイルを処理できるようにするために構文を変更したいと思います。ここでループを正しく書き換える方法は?

いくつかのデータ:巨大.csv考える

# Some data 
df <- 
    read.csv(textConnection('"ID","Name","City","Age" 
"1","Steve","Boston",33 
"2","Michael","Dallas",45 
"3","John","New York",89 
"4","Thomas","LA",62 
"5","Clint","Paris",30'), 
    as.is=TRUE) 

head(df) 
    ID Name  City Age 
#1 1 Steve Boston 33 
#2 2 Michael Dallas 45 
#3 3 John New York 89 
#4 4 Thomas  LA 62 
#5 5 Clint Paris 30 

# To create a XML file 
library(XML) 

# For each employee 
# Measure the execution 
start.time <- Sys.time() 

xml <- xmlTree() 
xml$addTag("Document", close=FALSE) 

for (i in 1:nrow(df)) { 
    xml$addNode("employee", attrs = c(id = df[i,"ID"]), close = FALSE) 
    appNames <- names(df)[names(df) != "ID"] 
    for (j in appNames) { 
    xml$addNode(j, df[i, j]) 
    } 
    xml$closeTag() 
} 
xml$closeTag() 

end.time <- Sys.time() 
time.taken <- end.time - start.time 
time.taken 

# Execution performance 
Time difference of 0.0321269 secs 

# How the XML looks like 
cat(saveXML(xml)) 
<?xml version="1.0"?> 

<Document> 
    <employee id="1"> 
    <Name>Steve</Name> 
    <City>Boston</City> 
    <Age>33</Age> 
    </employee> 
    <employee id="2"> 
    <Name>Michael</Name> 
    <City>Dallas</City> 
    <Age>45</Age> 
    </employee> 
    <employee id="3"> 
    <Name>John</Name> 
    <City>New York</City> 
    <Age>89</Age> 
    </employee> 
    <employee id="4"> 
    <Name>Thomas</Name> 
    <City>LA</City> 
    <Age>62</Age> 
    </employee> 
    <employee id="5"> 
    <Name>Clint</Name> 
    <City>Paris</City> 
    <Age>30</Age> 
    </employee> 
</Document> 

私はデータフレームを回避することが適切であるとリストを使用していますと思いました。

df1<- lapply(unique(df[,1]), function(x) df[df[,1] == x,]) 

df1[1] 

    ID Name City Age 
#1 1 Steve Boston 33 

今私は、ネストされたループの構造を変更し、サブリストにlappyを使用したい:

lapply(df1, function(v) xml$addNode("employee", attrs = c(ID = df1[[i,"ID"]]), close = FALSE)) 

それとも

lapply(df1, function(x) lapply(appNames, function(v) xml$addNode(j, df[i, j]))) 

ないしかしそれは正しいアプローチであるかどうか知りませんlapplyを使用して同じものにする方法XML

+0

「テーマ別」とはどういう意味ですか? –

+0

こんにちは@ScottHunter、混乱して申し訳ありません。主題については、リスト上でその関数を使用したいトピックをヒントしたかっただけです。それはもちろん他の話題でもあります。私はトピック内で再現可能な例を作るのは理にかなっていますが。 –

+0

あなたの 'df1'は' data.frame'のリストなので、あなたが勝つことを期待していますか?結果もリストに表示されますか?ですから、 'lapply'以外の要素を追加したり更新したりすることはできません(しかし、これは間違っているかもしれません)。 – drmariod

答えて

0

データフレームを避けるために、CSVをラインごとにスキャンすることを検討してください。小規模な文書では、これはうまくいかないかもしれませんが、大きなものでは役に立つかもしれませんし、csv全体をメモリに読み込まないようにしてください。また、以下では、newXMLDoc()newXMLNode、およびaddAttribtues()のメソッドを使用してXMLを別の方法で作成します。

file <- "/path/to/file.csv" 

# FIND NUMBER OF LINES (SKIP IF # OF ROWS IS KNOWN) 
con <- file(description=file, open="r") 
flines <- 0 
while((linesread <- length(readLines(con, n=-1L, warn=FALSE))) > 0){ 
    flines <- flines + linesread 
} 
close(con) 

doc = newXMLDoc()             # INITIATE XML DOC 
root = newXMLNode("Document", doc = doc)        # DEFINE ROOT 

# SCAN BY LINES 
con <- file(description=file, open="r") 
for(i in 1:flines) { 
    tmp <- scan(file=con, nlines=1, what = list("","","",""), sep=",", quiet=TRUE) 
    names(tmp) <- c('ID', 'Name', 'City', 'Age') 

    empNode = newXMLNode("employee", parent = root)     # EMPLOYEE NODE 
    addAttributes(empNode, id = tmp$ID)        # ID ATTRIB 

    for (j in 2:length(tmp)){   
    data <- newXMLNode(names(tmp)[j], tmp[[j]], parent = empNode) # CHILDREN 
    }  
} 
close(con) 
関連する問題