2016-04-02 2 views
0

Я хочу проанализировать дорожку gpx в R. Чтобы импортировать данные, я пытаюсь использовать XML-package.Импорт gpx-трека с использованием библиотеки XML

Я нашел 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 

Теперь, вместо RootNode, я хотел бы импортировать содержание <trkseg> в dataframe. Он должен быть выполнен следующим образом:

  • Каждый trkseg должен быть ряд
  • trkpt lon, trkpt lat, <ele> и <time> должны быть в соответствующих столбцах
  • Если значение <gpxtpx:hr> оно должно также идти в соответствующая колонка

Помогите мне достичь этого?

+0

Можете ли вы показать код, который вы до сих пор для выполнения этой обработки? Можете ли вы просто создать функцию, которая обрабатывает соответствующий узел, который будет предоставлять значение по умолчанию, если «hr» ребенок не существует? – steveb

+0

Код, который я использовал до сих пор, связан в моем вопросе: http://www.r-bloggers.com/stay-on-track-plotting-gps-tracks-with-r/ или 'elevations <- as.numeric (xpathSApply (gpx.raw, path = "// trkpt/ele", xmlValue)) '(и аналогичный). Это, однако, не кажется довольно элегантным, так как он всегда импортирует столбцы один за другим. Из структуры файла gpx можно, по крайней мере, теоретически, импортировать все соответствующие данные сразу. Если это невозможно, может возникнуть способ заменить все отсутствующие узлы 'hr' на' NA' – speendo

+1

Сглаживание вложенных xml-файлов (imho) всегда является болью. Попробуйте sth как 'lst <- xmlToList (rootNode); do.call (plyr :: rbind.fill, lapply (lst $ trk $ trkseg, function (x) as.data.frame (t (unlist (x)), strAsAsFactors = F))) 'для стартера. _ «Каждый trkseg должен быть строкой» _ - что, если каждый trkseg содержит несколько значений lon/lat/etc, т. Е. Если он может содержать более одной строки? – lukeA

ответ

0

Это код, в котором я оказался. Спасибо всем вам (особенно @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.

Интересно, есть ли более элегантный способ, но, по крайней мере, это похоже на работу.

0

Вот версия похожа на ответ от @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)) 
Смежные вопросы