我有一个以XML格式记录数据的水族馆监控系统,我在本地检索这些数据。下面是一个结构的例子;
<datalog>
<record>
<date>20210301 00:00</date>
<probe>
<name>Tank1Temp</name>
<type>Temperature</type>
<value>10.4</value>
</probe>
<probe>
<name>Tank1Sal</name>
<type>Salinity</type>
<value>28.0</value>
</probe>
<probe>
<name>Tank1pH</name>
<type>pH</type>
<value>8.0</value>
</probe>
</record>
<record>
<date>20210301 00:01</date>
<probe>
<name>Tank1Temp</name>
<type>Temperature</type>
<value>10.5</value>
</probe>
<probe>
<name>Tank1Sal</name>
<type>Salinity</type>
<value>28.1</value>
</probe>
<probe>
<name>Tank1pH</name>
<type>pH</type>
<value>8.0</value>
</probe>
</record>
</datalog>
这是一个非常简单的例子,记录在24小时内每分钟记录一次,所以这个块每天重复1440次。与上面的三个例子相比,每条记录的探测次数也要多得多。
我想把它变成一个包含"日期"、"名称"、"类型"、"值"等列的数据框架。我在网上遇到过类似的问题,但没有一个解决方案适合我。我认为这是因为探测器都嵌套在日期中,并且示例更"简单",并且没有解释如何处理嵌套结构。
到目前为止,我可以让R从系统读取数据(它连接到只能在本地访问的路由器),但一旦在R中我就丢失了。我尝试使用以下代码;
dataframe <- xmlToDataFrame(getNodeSet(data.20210225, c("//record/date", "//record/probe")))
生成的数据帧看起来像;
考虑扩展你的数据帧处理,用xpathApply
建立一个单独的<record>
级数据帧的列表,最后在rbind
编译:
recds <- xpathApply(data.20210225, "//record", function(x) {
# ADD CLEANED NEW date COLUMN
df <- within(xmlToDataFrame(x), { date <- text[1] })
# RE-ORDER/SUBSET COLS, DROP FIRST ROW, RESET ROWNAMES
data.frame(df[-1, c("date", "name", "type", "value")], row.names=NULL)
})
final_df <- do.call(rbind, recds)
final_df
# date name type value
# 1 20210301 00:00 Tank1Temp Temperature 10.4
# 2 20210301 00:00 Tank1Sal Salinity 28.0
# 3 20210301 00:00 Tank1pH pH 8.0
# 4 20210301 00:01 Tank1Temp Temperature 10.5
# 5 20210301 00:01 Tank1Sal Salinity 28.1
# 6 20210301 00:01 Tank1pH pH 8.0