从R

时间:2017-05-10 13:26:08

标签: r xml gps

我正在尝试分析包含多圈的.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类,然后我无法使用ldplygetNodeSet nodes2。我玩过xmlApplyxmlToList,但没有运气。

我也尝试了一个使用循环的方法,但在那里甚至有问题。貌似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)

1 个答案:

答案 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
...