First, let's load up our data. The data are available in a gist. You can convert your own GPS data to .csv by following the instructions here, using gpsbabel.

```
gps <- read.csv("callan.csv",
header = TRUE)
```

Next, we can use the function `SMA`

from the package **TTR** to calculate a moving average of the altitude or elevation data, if we want to smooth out the curve. We can define a constant for the number of data points we want to average to create each moving average value.

If you don't want to convert meters to feet, a metric version of the code is available in the gist (callanMetric.R).

```
library(TTR)
movingN <- 5 # define the n for the moving average calculations
gps$Altitude <- gps$Altitude * 3.281 # convert m to ft
gps$SMA <- SMA(gps$Altitude,
n = movingN)
gps <- gps[movingN:length(gps$SMA), ] # remove first n-1 points
```

Next, we want to calculate the distance of each point. You can skip this step if your dataset already includes distances.

```
library(sp)
Dist <- 0
for(i in 2:length(gps$Longitude)) {
Dist[i] = spDistsN1(as.matrix(gps[i,c("Longitude", "Latitude")]),
c(gps$Longitude[i-1], gps$Latitude[i-1]),
longlat = TRUE) / 1.609 # longlat so distances will be in km, then divide to convert to miles
}
gps$Dist <- Dist
DistTotal <- 0
for(i in 2:length(gps$Longitude)) {
DistTotal[i] = Dist[i] + DistTotal[i-1]
}
gps$DistTotal <- DistTotal
```

And finally, we can plot our elevation data using geom_ribbons and ggplot:

```
library(ggplot2)
ggplot(gps, aes(x = DistTotal)) +
geom_ribbon(aes(ymin = 600, # change this to match your min below
ymax = SMA),
fill = "#1B9E77") + # put your altitude variable here if not using moving averages
labs(x = "Miles",
y = "Elevation") +
scale_y_continuous(limits = c(600,1200)) # change this to limits appropriate for your region
```