使用 XML 库导入 gpx 轨迹
Import gpx track using the XML library
我想在 R 中分析一个 gpx 轨迹。要导入数据,我尝试使用 XML-package。
我发现 a tutorial 解释了如何导入每个单独的数据向量,然后将它们组合到一个数据框中。
但是,在我的用例中,这不起作用,因为对于某些节点,没有收集心率 <gpxtpx:hr>
,因此向量的长度不匹配。
因此我尝试一次导入所有相关数据。
到目前为止我设法做到的是
library(XML)
filename <- "sample.gpx"
download.file("https://owncloud.yeara.net/index.php/s/Io4uOq6sfFuCCdq/download", filename) # downloads a sample file from my server
gpx.raw <- xmlTreeParse(filename, useInternalNodes = TRUE)
rootNode <- xmlRoot(gpx.raw)
print(rootNode) # output seems okay
现在,我想将 <trkseg>
的内容导入数据框,而不是根节点。应该这样设计:
- 每个
trkseg
应该是一行
trkpt lon
、trkpt lat
、<ele>
和 <time>
应在相应的列中
- 如果有一个值
<gpxtpx:hr>
,它也应该进入相应的列
你能帮我实现这个吗?
这是我最终得到的代码。感谢大家(尤其是@lukeA)的帮助。
library(XML)
library(plyr)
filename <- "Downloads/activity(1).gpx"
gpx.raw <- xmlTreeParse(filename, useInternalNodes = TRUE)
rootNode <- xmlRoot(gpx.raw)
gpx.rawlist <- xmlToList(rootNode)$trk
gpx.list <- unlist(gpx.rawlist[names(gpx.rawlist) == "trkseg"], recursive = FALSE)
gpx <- do.call(rbind.fill, lapply(gpx.list, function(x) as.data.frame(t(unlist(x)), stringsAsFactors=F)))
names(gpx) <- c("ele", "time", "hr", "lon", "lat")
我在使用多个 trkseg
时遇到了一些问题,因为我无法通过名称访问它们(因为它们在列表中都具有相同的名称:trkseg
)我可以使用 unlist
命令和 gpx.rawlist
.
中元素的棘手选择
我想知道是否有更优雅的方法,但至少这似乎有效。
这是一个类似于@speendo 的答案的版本,但使用了 dplyr 和 purrr:
library(XML)
library(dplyr)
library(purrr)
filename <- "Downloads/activity(1).gpx"
gpx <- filename %>%
xmlTreeParse(useInternalNodes = TRUE) %>%
xmlRoot %>%
xmlToList %>%
(function(x) x$trk) %>%
(function(x) unlist(x[names(x) == "trkseg"], recursive = FALSE)) %>%
map_df(function(x) as.data.frame(t(unlist(x)), stringsAsFactors=FALSE))
我想在 R 中分析一个 gpx 轨迹。要导入数据,我尝试使用 XML-package。
我发现 a tutorial 解释了如何导入每个单独的数据向量,然后将它们组合到一个数据框中。
但是,在我的用例中,这不起作用,因为对于某些节点,没有收集心率 <gpxtpx:hr>
,因此向量的长度不匹配。
因此我尝试一次导入所有相关数据。
到目前为止我设法做到的是
library(XML)
filename <- "sample.gpx"
download.file("https://owncloud.yeara.net/index.php/s/Io4uOq6sfFuCCdq/download", filename) # downloads a sample file from my server
gpx.raw <- xmlTreeParse(filename, useInternalNodes = TRUE)
rootNode <- xmlRoot(gpx.raw)
print(rootNode) # output seems okay
现在,我想将 <trkseg>
的内容导入数据框,而不是根节点。应该这样设计:
- 每个
trkseg
应该是一行 trkpt lon
、trkpt lat
、<ele>
和<time>
应在相应的列中- 如果有一个值
<gpxtpx:hr>
,它也应该进入相应的列
你能帮我实现这个吗?
这是我最终得到的代码。感谢大家(尤其是@lukeA)的帮助。
library(XML)
library(plyr)
filename <- "Downloads/activity(1).gpx"
gpx.raw <- xmlTreeParse(filename, useInternalNodes = TRUE)
rootNode <- xmlRoot(gpx.raw)
gpx.rawlist <- xmlToList(rootNode)$trk
gpx.list <- unlist(gpx.rawlist[names(gpx.rawlist) == "trkseg"], recursive = FALSE)
gpx <- do.call(rbind.fill, lapply(gpx.list, function(x) as.data.frame(t(unlist(x)), stringsAsFactors=F)))
names(gpx) <- c("ele", "time", "hr", "lon", "lat")
我在使用多个 trkseg
时遇到了一些问题,因为我无法通过名称访问它们(因为它们在列表中都具有相同的名称:trkseg
)我可以使用 unlist
命令和 gpx.rawlist
.
我想知道是否有更优雅的方法,但至少这似乎有效。
这是一个类似于@speendo 的答案的版本,但使用了 dplyr 和 purrr:
library(XML)
library(dplyr)
library(purrr)
filename <- "Downloads/activity(1).gpx"
gpx <- filename %>%
xmlTreeParse(useInternalNodes = TRUE) %>%
xmlRoot %>%
xmlToList %>%
(function(x) x$trk) %>%
(function(x) unlist(x[names(x) == "trkseg"], recursive = FALSE)) %>%
map_df(function(x) as.data.frame(t(unlist(x)), stringsAsFactors=FALSE))