我正在尝试分析包含多圈的.tcx文件中的一些GPS数据。我想做一些与this非常相似的事情 - 基本上将每个跟踪点提取到数据帧中以供进一步分析。但我需要保留每一圈的信息。
我是一个完整的xml新手 - 我的失败尝试在下面,以及我的数据摘录。请注意,当我创建测试数据时,我的GPS失败时位置数据丢失了。假装每个跟踪点都包含lat和long。
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类,然后我无法使用ldply
或getNodeSet
nodes2
。我玩过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>
从好的方面来说,我得到的输出包括LapTime for StartTime下的属性,这可以是最终数据帧的内容。我想所有需要调整的是
xpathSApply(doc, "//Trackpoint/..", xmlSize)
答案 0 :(得分:1)
这应该得到你的跟踪点数据......
x <- xmlToDataFrame(doc["//Trackpoint"])
如果需要从父节点向该表添加值或属性,则获取父节点(6和6)的大小并重复属性或值(因为您没有,我重复数字)。 / p>
n <- xpathSApply(doc, "//Lap/Track", xmlSize) #OR
n <- xpathSApply(doc, "//Trackpoint/..", xmlSize)
# if Lap had an attribute
x$Lap <- rep( xpathSApply(doc, "//Lap", xmlGetAttr, "number"), n)
x$Lap <- rep( 1:length(n), n)
x
Time SensorState Lap
1 2017-05-03T08:22:56.000Z Present 1
2 2017-05-03T08:22:57.000Z Present 1
3 2017-05-03T08:22:58.000Z Present 1
4 2017-05-03T08:22:59.000Z Present 1
5 2017-05-03T08:23:00.000Z Present 1
6 2017-05-03T08:23:01.000Z Present 1
7 2017-05-03T08:23:02.000Z Present 2
8 2017-05-03T08:23:03.000Z Present 2
...