Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read multiple .gpx files

Tags:

loops

r

gps

gis

Suppose I have a number of .gpx files (these contain GPX waypoint data from a Garmin eTrex). I want to load them into R with different names and manipulate them.

I can read one file thus:

library(maptools)
gpx.raw <- readGPS(i = "gpx", f = "file1_w_12_f_ddf.gpx", type="w")

Suppose I want to read a number of them into memory. I could try a for loop:

files <- list.files(".",pattern = "*.gpx")
for(x in files){

    #Create new file name
    temp <- strsplit(x,"_",fixed=TRUE)
    visit.id <- sapply(temp,FUN=function(x){paste(x[1],x[4],substr(x[5],1,3),sep="_")})

    #read file with new filename
    assign(visit.id, readGPS(i = "gpx", f = x, type="w"))
}

Running above program yields following error:

Error in read.table(con <- textConnection(gpsdata), fill = TRUE, ...) : no lines available in input In addition: Warning message: running command 'C:\PROGRA~2\GPSBabel\gpsbabel.exe -w -i gpx -f file1_w_12_f_ddf.gpx -o tabsep -F -' had status 1

Note that I was able to read this file on its own, so it would seem it has nothing to do with the file itself but with running readGPS in a loop.

In general I still find it very confusing how R treats variables like x above. I am not sure how to modify the argument to readGPS from the stand alone instance f = "file1_w_12_f_ddf.gpx": Should it be x, or f = x, or f = "x", or what? Or maybe the problem is in the call to GPSBabel...

I include a sample file below so you can copy it to text editor, and save as .gpx. twice with different names and try yourself.

<?xml version="1.0" encoding="UTF-8"?>
<gpx
 version="1.0"
 creator="GPSBabel - http://www.gpsbabel.org"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://www.topografix.com/GPX/1/0"
 xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
 <time>2010-09-14T18:35:43Z</time>
 <bounds minlat="18.149888897" minlon="-96.747799935" maxlat="50.982883293" maxlon="121.640266674"/>
<wpt lat="38.855549991" lon="-94.799016668">
<ele>325.049072</ele>
 <name>GARMIN</name>
 <cmt>GARMIN</cmt>
 <desc>GARMIN</desc>
 <sym>Flag</sym>
 </wpt>
 <wpt lat="50.982883293" lon="-1.463899976">
 <ele>35.934692</ele>
 <name>GRMEUR</name>
 <cmt>GRMEUR</cmt>
 <desc>GRMEUR</desc>
 <sym>Flag</sym>
 </wpt>
 <wpt lat="25.061783362" lon="121.640266674">
 <ele>38.097656</ele>
 <name>GRMTWN</name>
 <cmt>GRMTWN</cmt>
 <desc>GRMTWN</desc>
 <sym>Flag</sym>
 </wpt>
 </gpx>

NOTE: To run readGPS you will need the open source GPSBabel program installed and referenced in your PATH variable.

like image 322
Fred Avatar asked Jun 18 '11 17:06

Fred


1 Answers

Fred,

After installing GPSBabel and updating the PATH variable, your code snippet ran fine. I have two objects names test1.gpx_NA_NA and test2.gpx_NA_NA with three observations of 28 variables. Is that right? I assume the NA bit in the file names is due to how you are defining visit.id and my test file names not fitting into that paradigm.

Have you tried this on a fresh instance of R?

FWIW, I would probably read all of these files into a single list object. I find dealing with a list object easier than having lots of different objects floating around. For example,

files <- dir(pattern = "\\.gpx")
#Replace all space characters with a "_". Replace with the character of your choice.
lapply(files, function(x) file.rename(from = x, to = gsub("\\s+", "_", x)))

#Reread in files with better names:
files <- dir(pattern = "\\.gpx")
out <- lapply(files, function(x) readGPS(i = "gpx", f = x, type = "w"))
names(out) <- files

and out is now a list of 2, where each object is a data.frame with the name of the file that it was associated with previously. Using something from the *apply family has the benefit leaving a clean working space behind as well. Using the for-loop results in x, temp, and visit.id hanging out afterwords. You could wrap them up into a function call, but just using lapply will be more straight forward I think.

like image 56
Chase Avatar answered Oct 03 '22 20:10

Chase