【问题标题】:Extract GPS data from XML in R从 R 中的 XML 中提取 GPS 数据
【发布时间】: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 &lt;- getNodeSet(doc, "//ns:Track", "ns") 成功地将 xml 分解成类似于列表的东西,但属于 XMLNodeSet 类,然后我不能在nodes2 上使用ldplygetNodeSet。我玩过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 有一些更高的级别,&lt;TrainingCenterDatabase&gt;&lt;Activities&gt;&lt;Activity&gt;。就像我说的,我是一个完整的初学者。这是另一个与上一个格式相同的 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 等等?”

标签: r xml gps


【解决方案1】:

这应该会获取您的跟踪点数据...

x <- xmlToDataFrame(doc["//Trackpoint"])

如果您需要从父节点向该表添加值或属性,则获取父节点的大小(6 和 6)并重复属性或值(因为您都没有,所以我重复了数字)。

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

【讨论】:

  • 谢谢,没想到拉出父节点的大小。看起来它应该解决问题,一旦我尝试过,期待一个支持。
  • 所以您的解决方案适用于我提供的数据提取,但事实证明我在获取子集时犯了错误。我已经为这个问题添加了一个更新,如果你能再看看并提供更多建议,我将不胜感激。谢谢,詹姆斯
  • 我会发布另一个问题。 xmlToDataFrame 仅适用于简单的 XML 结构,我提到的解决方法在非常有限的情况下有效,但现在您有一个非常复杂的文件,并且有许多可能的解决方案。
  • 是的,我认为一个新的问题是要走的路。我设法通过提取每圈触发的时间并计算出每个跟踪点必须在哪一圈找到解决方法,但感觉有点像作弊,因为整点都是自学 XML。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多