多くのXMLファイル(約100,000)があります。各ファイルには約100点のノードがあります。私は説明のためにそれらの5つだけを示します。多くのXMLファイルを1つのデータフレームにまとめます。
<?xml version="1.0" encoding="UTF-8"?>
-<car id="id1">
<point time="1272686841" lon="-122.40648" lat="37.79778" status="E" unit="id1"/>
<point time="1272686781" lon="-122.40544" lat="37.79714" status="M" unit="id1"/>
<point time="1272686722" lon="-122.40714" lat="37.79774" status="M" unit="id1"/>
<point time="1272686661" lon="-122.40704" lat="37.7976" status="M" unit="id1"/>
<point time="1272686619" lon="-122.40616" lat="37.79698" status="E" unit="id1"/>
</car>
私は5列(時間、経度、緯度、ユニット、状態)とR中(約100,000x100 = 10,000,000行の)一つの大きなデータフレームにすべてのこれらのXMLファイルをマージしたいです。すべてのファイルに同じ5つの変数がありますが、順序は異なっていてもかまいません。
以下は私のコードです。まず、これらの5つの変数を保存する5つのベクトルを作成します。それから私は各ファイルに行き、エントリーを一つ一つ読む。
setwd("C:\\Users\\MyName\\Desktop\\XMLTest")
all.files <- list.files()
n <- 2000000
all.lon <- rep(NA, n)
all.lat <- rep(NA, n)
all.time <- rep(NA, n)
all.status <- rep(NA, n)
all.unit <- rep(NA, n)
i <- 1
for (cur.file in all.files) {
if (tolower(file_ext(cur.file)) == "xml") {
xmlfile <- xmlTreeParse(cur.file)
xmltop <- xmlRoot(xmlfile)
for (j in 1:length(xmltop)) {
cur.node <- xmltop[[j]]
cur.lon <- as.numeric(xmlGetAttr(cur.node, "lon"))
cur.lat <- as.numeric(xmlGetAttr(cur.node, "lat"))
cur.time <- as.numeric(xmlGetAttr(cur.node, "time"))
cur.unit <- xmlGetAttr(cur.node, "unit")
cur.status <- xmlGetAttr(cur.node, "status")
all.lon[i] <- cur.lon
all.lat[i] <- cur.lat
all.time[i] <- cur.time
all.status[i] <- cur.status
all.unit[i] <- cur.unit
i <- i + 1
}
}
}
これは私が今できる最善の方法です。問題はそれが非常に遅いことです。 1つの理由は、非常に多くのファイルがあることです。もう1つの理由は、for
ループfor (j in 1:length(xmltop))
です。私はxmlToDataFrame
を試しましたが、動作しません。
> xmlToDataFrame(cur.file)
Error in matrix(vals, length(nfields), byrow = TRUE) :
'data' must be of a vector type, was 'NULL'
このプロセスをスピードアップする方法はありますか?
すべてのXMLファイルが同じに見える場合は、私は非常に高速だと思いますが、生の文字列を返す 'readLines'を試すことができます。次に、 'lapply'関数で文字列から関連する値を抽出することができます。 –
xml2パッケージを使用すると、少数のステートメントでファイル全体を処理できるはずです。 xml2パッケージのxml_nodes関数とxml_attr関数を参照してください。これにより、改善されたパフォーマンスのために内部ループがなくなります。 – Dave2e
@ Dave2e 'xml2'パッケージを見ていきます。ありがとう。 –