pronto is a simple R package for interacting with data from from Seattle's Pronto cycle sharing system. Data comes from Pronto's data stream, which is described here.
This project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.
pronto
is not on CRAN, but you can install the latest and greatest version using devtools:
if(!require("devtools")) install.packages("devtools")
devtools::install_github("briandconnelly/pronto")
library(pronto)
s <- pronto_stations()
The result, s
, is a list containing a timestamp
for the data, whether or not rentals across the system are suspended (schemeSuspended
), and a data frame containing information about all of the stations (stations
).
The first five rows of stations
look like this:
| id| s | n | st| b | su | m | lu| lc| bk | bl | la| lo| da| dx| ba| bx| |----:|:-----------------------|:-------|----:|:------|:------|:------|-------------:|-------------:|:------|:------|---------:|----------:|----:|----:|----:|----:| | 1| 3rd Ave & Broad St | BT-01 | 1| FALSE | FALSE | FALSE | 1.458057e+12| 1.458066e+12| FALSE | FALSE | 47.61842| -122.3510| 10| 0| 7| 1| | 2| 2nd Ave & Vine St | BT-03 | 1| FALSE | FALSE | FALSE | 1.458058e+12| 1.458066e+12| TRUE | TRUE | 47.61583| -122.3486| 11| 0| 4| 1| | 3| 6th Ave & Blanchard St | BT-04 | 1| FALSE | FALSE | FALSE | 1.458064e+12| 1.458066e+12| TRUE | TRUE | 47.61609| -122.3411| 8| 0| 7| 1| | 4| 2nd Ave & Blanchard St | BT-05 | 1| FALSE | FALSE | FALSE | 1.458059e+12| 1.458066e+12| TRUE | TRUE | 47.61311| -122.3442| 7| 0| 5| 1| | 5| 2nd Ave & Pine St | CBD-13 | 1| FALSE | FALSE | FALSE | 1.458062e+12| 1.458066e+12| TRUE | TRUE | 47.61018| -122.3396| 9| 1| 6| 2|
Although Pronto's API doesn't support querying a single station, we can easily filter the station data using dplyr.
library(pronto)
library(dplyr)
s <- pronto_stations()
# Get information about the station near Fred Hutch
s_fhcrc <- s$stations %>%
filter(id == 22)
Let's make a map of current bike availability across the city using ggmap.
library(pronto)
library(dplyr)
library(magrittr)
library(ggplot2)
library(ggmap)
s <- pronto_stations()
avail <- s$stations %>%
filter(su == FALSE) %>%
summarise(StationsAvail=n(), BikesAvail=sum(ba))
map <- get_map(location = c(lon=mean(range(s$stations$lo)),
lat=mean(range(s$stations$la))),
zoom = 13, maptype = "toner-lite")
p <- ggmap(map) +
geom_point(data = s$stations,
aes(x=lo, y=la, size=ba, color=ba), alpha = 0.6) +
scale_size_area(guide=FALSE) +
scale_color_continuous(name = "Bikes") +
scale_alpha_continuous(guide = FALSE) +
ggtitle(sprintf("%d bikes available at %d stations", avail$BikesAvail, avail$StationsAvail)) +
theme_minimal() +
theme(axis.text = element_blank()) +
theme(axis.title = element_blank()) +
theme(legend.title = element_text(size = rel(0.8))) +
theme(legend.text = element_text(size = rel(0.6))) +
theme(legend.key.size = unit(0.8, "lines"))
p
Let's spice it up. Here, we'll get the station data every 60 seconds for one hour and then create an animated map using gganimate. Note: this code will take an hour to run.
For extra credit, we could show the time stamps in a more friendly format or interpolate the data using tweenr.
library(pronto)
library(dplyr)
library(ggplot2)
library(ggmap)
library(gganimate)
stationdata <- data.frame()
for (i in seq(60)) {
s <- pronto_stations()
s$stations$timestamp <- s$timestamp
stationdata <- bind_rows(stationdata, s$stations)
Sys.sleep(60)
}
map <- get_map(location = c(lon=mean(range(s$stations$lo)), lat=mean(range(s$stations$la))),
zoom = 13, maptype = "toner-lite")
p <- ggmap(map) +
geom_point(data = stationdata,
aes(x=lo, y=la, size=ba, color=ba, frame = timestamp),
alpha = 0.6) +
scale_size_area(guide=FALSE) +
scale_color_continuous(name = "Bikes") +
scale_alpha_continuous(guide = FALSE) +
theme_minimal() +
theme(axis.text = element_blank()) +
theme(axis.title = element_blank()) +
theme(legend.title = element_text(size = rel(0.8))) +
theme(legend.text = element_text(size = rel(0.6))) +
theme(legend.key.size = unit(0.8, "lines"))
gg_animate(p, pause = 0.5, title_frame = FALSE)
We've just picked up some wine at Pete's and need to get to the party. To find the nearest bike, we can use fossil to calculate the distances between our location (here
) and each station. Unfortunately, this won't tell you about hills.
library(pronto)
library(fossil)
library(dplyr)
library(magrittr)
here <- list(lo = -122.329401, la = 47.639821)
closest_station <- pronto_stations()$stations %>%
mutate(dist_km = deg.dist(.$lo, .$la, here$lo, here$la)) %>%
arrange(dist_km) %>%
filter(st == 1) %>% # the station is in service
filter(ba > 0) %>% # there's a bike available
head(n = 1)
cat(sprintf("The %s station is %.02f km away and has %d bike(s) available",
closest_station$s, closest_station$dist_km, closest_station$ba))
#> The E Blaine St & Fairview Ave E station is 0.59 km away and has 5 bike(s) available
Neither this package nor its contributer(s) are affiliated with Pronto.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.