【发布时间】:2017-05-10 13:26:08
【问题描述】:
我正在尝试分析包含多圈的 .tcx 文件中的一些 GPS 数据。我想做一些与this 非常相似的事情 - 基本上将每个跟踪点提取到数据框中以进行进一步分析。但我需要保留定义每一圈的信息。
我是一个完整的 xml 新手 - 下面是我失败的尝试,以及我的数据提取。请注意,当我创建测试数据时,由于我的 GPS 失败,位置数据丢失了。假设每个跟踪点也包含纬度和经度。
library(XML)
library(plyr)
doc <- xmlInternalTreeParse("test.tcx")
doc
<Lap>
<Track>
<Trackpoint>
<Time>2017-05-03T08:22:56.000Z</Time>
<SensorState>Present</SensorState>
</Trackpoint>
<Trackpoint>
<Time>2017-05-03T08:22:57.000Z</Time>
<SensorState>Present</SensorState>
</Trackpoint>
<Trackpoint>
<Time>2017-05-03T08:22:58.000Z</Time>
<SensorState>Present</SensorState>
</Trackpoint>
<Trackpoint>
<Time>2017-05-03T08:22:59.000Z</Time>
<SensorState>Present</SensorState>
</Trackpoint>
<Trackpoint>
<Time>2017-05-03T08:23:00.000Z</Time>
<SensorState>Present</SensorState>
</Trackpoint>
<Trackpoint>
<Time>2017-05-03T08:23:01.000Z</Time>
<SensorState>Present</SensorState>
</Trackpoint>
</Track>
</Lap>
<Lap>
<Track>
<Trackpoint>
<Time>2017-05-03T08:23:02.000Z</Time>
<SensorState>Present</SensorState>
</Trackpoint>
<Trackpoint>
<Time>2017-05-03T08:23:03.000Z</Time>
<SensorState>Present</SensorState>
</Trackpoint>
<Trackpoint>
<Time>2017-05-03T08:23:04.000Z</Time>
<SensorState>Present</SensorState>
</Trackpoint>
<Trackpoint>
<Time>2017-05-03T08:23:05.000Z</Time>
<SensorState>Present</SensorState>
</Trackpoint>
<Trackpoint>
<Time>2017-05-03T08:23:06.000Z</Time>
<SensorState>Present</SensorState>
</Trackpoint>
<Trackpoint>
<Time>2017-05-03T08:23:07.000Z</Time>
<SensorState>Present</SensorState>
</Trackpoint>
</Track>
</Lap>
> nodes <- getNodeSet(doc, "//ns:Trackpoint", "ns")
> ldply(nodes, as.data.frame(xmlToList))
value.Time value.SensorState
1 2017-05-03T08:22:56.000Z Present
2 2017-05-03T08:22:57.000Z Present
3 2017-05-03T08:22:58.000Z Present
4 2017-05-03T08:22:59.000Z Present
5 2017-05-03T08:23:00.000Z Present
6 2017-05-03T08:23:01.000Z Present
7 2017-05-03T08:23:02.000Z Present
...
如您所见,按照该答案中的步骤,我可以到达 90%,但我丢失了单圈信息。我已经尝试按圈数/赛道拆分数据(我还没有弄清楚是否有一个不是紧跟在前面的,但这并不重要),但后来又努力让它更进一步。
nodes2 <- getNodeSet(doc, "//ns:Track", "ns") 成功地将 xml 分解成类似于列表的东西,但属于 XMLNodeSet 类,然后我不能在nodes2 上使用ldply 或getNodeSet。我玩过xmlApply 和xmlToList,但没有运气。
我也尝试了一些使用循环的问题,但在那里甚至遇到了问题。看似getNodeSet(nodes2[[i]],...) 对nodes2 中包含的所有跟踪点执行操作,而不仅仅是nodes2[[i]] 中的跟踪点。
test <- nodes2[[1]]
#successfully pulls out just the 6 trackpoints in lap 1
ldply(getNodeSet(test,"//ns:Trackpoint", "ns"), as.data.frame(xmlToList))
#creates a dataframe containing all 18 trackpoints in `nodes`.
所以我对此完全感到困惑。
另一种选择不是按圈数拆分数据,而是拥有一个带有圈数因子变量的大数据框。我能想到的唯一方法就是这样一团糟,让人有点作呕。
非常感谢任何朝着正确方向提出的建议或推动。
提前致谢,
詹姆斯
更新:结果我做了一个简化输入数据的哈希并删除了一些需要的信息。 Chris S 的解决方案适用于提取我最初包含的数据,但 XML 有一些更高的级别,<TrainingCenterDatabase>、<Activities> 和 <Activity>。就像我说的,我是一个完整的初学者。这是另一个与上一个格式相同的 XML 文档的开头。
<TrainingCenterDatabase>
<Activities>
<Activity Sport="Other">
<Id>2017-05-11T08:27:04.000Z</Id>
<Lap StartTime="2017-05-11T08:27:05.000Z">
<TotalTimeSeconds>106.0</TotalTimeSeconds>
<DistanceMeters>157.1999969482422</DistanceMeters>
<MaximumSpeed>1.6944444179534912</MaximumSpeed>
<Calories>20</Calories>
<Intensity>Active</Intensity>
<TriggerMethod>Manual</TriggerMethod>
<Track>
<Trackpoint>
<Time>2017-05-11T08:27:05.000Z</Time>
<Position>
<LatitudeDegrees>51.50305517</LatitudeDegrees>
<LongitudeDegrees>-0.09115383</LongitudeDegrees>
</Position>
<DistanceMeters>1.6944444179534912</DistanceMeters>
<SensorState>Present</SensorState>
</Trackpoint>
<Trackpoint>
<Time>2017-05-11T08:27:06.000Z</Time>
<Position>
<LatitudeDegrees>51.50305517</LatitudeDegrees>
<LongitudeDegrees>-0.09115383</LongitudeDegrees>
</Position>
<DistanceMeters>3.3888888359069824</DistanceMeters>
<SensorState>Present</SensorState>
</Trackpoint>
从好的方面来说,我的输出包括了 Lap 下的 StartTime 属性,这可能是最终数据帧中的内容。我认为所有需要调整的是
xpathSApply(doc, "//Trackpoint/..", xmlSize)
【问题讨论】:
-
你想要的输出是什么? 我丢失了 Lap 信息 ... Lap 节点本身不携带任何属性或文本的信息是什么?
-
@Parfait 通过圈速信息,我的意思是“此时我在哪一圈?1、2、3 等等?”