グレート答え!将来の読者にとって、Rインポートを必要とする複雑なXMLに直面するときはいつでも、XSLT(XMLコンテンツを様々な最終用途のニーズに操作する特殊目的の宣言型プログラミング言語)を使用してXML文書を再構成することを検討してください。それから、単にXMLパッケージのRのxmlToDataFrame()
関数を使用します。
Rには、すべてのオペレーティングシステムでCRAN-Rで使用できる専用のXSLTパッケージがありません。記載されているSXLTはLinuxパッケージのようですが、Windowsでは使用できません。未回答の質問hereとhereを参照してください。私は@hrbrmstr(上記)がGitHub XSLT projectを維持していることを理解しています。それにもかかわらず、ほぼすべての汎用言語は、Java、C#、Python、PHP、Perl、およびVBなどのXSLTプロセッサを維持しています。
以下はオープンソースのPythonのルートです.XSLドキュメントはかなり微妙なので、2つのXSLTが使用されています(もちろん、XSLTのガウスはそれらを1つに組み合わせることができますが、(recursive templateを使用して)
FIRST XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- Identity Transform -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="record/text()" name="tokenize">
<xsl:param name="text" select="."/>
<xsl:param name="separator" select="' '"/>
<xsl:choose>
<xsl:when test="not(contains($text, $separator))">
<data>
<xsl:value-of select="normalize-space($text)"/>
</data>
</xsl:when>
<xsl:otherwise>
<data>
<xsl:value-of select="normalize-space(substring-before($text, $separator))"/>
</data>
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="substring-after($text, $separator)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="description|variables|categoricalvariable|realvariable">
</xsl:template>
SECOND XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Identity Transform -->
<xsl:template match="records">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="record">
<record>
<area_name><xsl:value-of select="@label"/></area_name>
<area><xsl:value-of select="data[1]"/></area>
<region><xsl:value-of select="data[2]"/></region>
<palmitic><xsl:value-of select="data[3]"/></palmitic>
<palmitoleic><xsl:value-of select="data[4]"/></palmitoleic>
<stearic><xsl:value-of select="data[5]"/></stearic>
<oleic><xsl:value-of select="data[6]"/></oleic>
<linoleic><xsl:value-of select="data[7]"/></linoleic>
<linolenic><xsl:value-of select="data[8]"/></linolenic>
<arachidic><xsl:value-of select="data[9]"/></arachidic>
<eicosenoic><xsl:value-of select="data[10]"/></eicosenoic>
</record>
</xsl:template>
</xsl:stylesheet>
(lxmlのモジュールを使用して)Pythonの
余分なスペースは、XML文書に "NA" の後に追加されたとして
import lxml.etree as ET
cd = os.path.dirname(os.path.abspath(__file__))
# FIRST TRANSFORMATION
dom = ET.parse('http://www.ggobi.org/book/data/olive.xml')
xslt = ET.parse(os.path.join(cd, 'Olive.xsl'))
transform = ET.XSLT(xslt)
newdom = transform(dom)
tree_out = ET.tostring(newdom, encoding='UTF-8', pretty_print=True, xml_declaration=True)
xmlfile = open(os.path.join(cd, 'Olive_py.xml'),'wb')
xmlfile.write(tree_out)
xmlfile.close()
# SECOND TRANSFORMATION
dom = ET.parse(os.path.join(cd, 'Olive_py.xml'))
xslt = ET.parse(os.path.join(cd, 'Olive2.xsl'))
transform = ET.XSLT(xslt)
newdom = transform(dom)
tree_out = ET.tostring(newdom, encoding='UTF-8', pretty_print=True, xml_declaration=True)
xmlfile = open(os.path.join(cd, 'Olive_py.xml'),'wb')
xmlfile.write(tree_out)
xmlfile.close()
R
library(XML)
# LOADING TRANSFORMED XML INTO R DATA FRAME
doc<-xmlParse("Olive_py.xml")
xmldf <- xmlToDataFrame(nodes = getNodeSet(doc, "//record"))
View(xmldf)
出力
area_name area region palmitic palmitoleic stearic oleic linoleic linolenic arachidic eicosenoic
North-Apulia 1 1 1075 75 226 7823 672 na 60
North-Apulia 1 1 1088 73 224 7709 781 31 61 29
North-Apulia 1 1 911 54 246 8113 549 31 63 29
North-Apulia 1 1 966 57 240 7952 619 50 78 35
North-Apulia 1 1 1051 67 259 7771 672 50 80 46
...
は、(非常に最初のレコードに若干のクリーンアップは、必要とされていますしたがって、arachidic
およびeicosenoic
は、前方にシフトされました)
Hadleyが一貫して非常に高品質で便利なRパッケージを作成しているため、xml2を使用します。それはおそらくもっとスムーズに進み、よりよく文書化されるでしょう。 readmeの下の相違点:https://github.com/hadley/xml2 –
十分に公正です。 xml2は、GitHubのページによると私の簡単な経験は、より簡単なインターフェイスを持っています。 RはRのコア開発者によって書かれたもので、奇妙なものでいっぱいですが、Hadleyはしばしばシンプルさとパワーバランスのバランスを取って、すべてをきれいに整えます。 –