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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With