简体   繁体   中英

R: Mapping multiple Routes using ggmap

I have been trying to make a different this lovely flowing data visualization for some time this week but keep hitting a snag in the final implementation.

Here is the data set I'm using. I have melded it into a frame with the three key bits of information I want to display: startinglatlong, endinglatlong, and number of trips.

I got closest using the idea posted here , but two hit a snag on two items:

1) making the size of the line change based on the number of trips 2) getting the google api to allow me to call this many rows (I have 55,704 in my data set).

counts is the name of my full df, with looks like so:

head(counts)
  X from_station_id.x to_station_id.x From_Station_Lat From_Station_Long    End_Station_Lat End_Station_Long   n                   eichel     
1 1                 5               5         41.87396         -87.62774        41.87396        -87.62774 275 41.87395806 -87.62773949  
2 2                 5              13         41.87396         -87.62774        41.93250        -87.65268   1 41.93250008 -87.65268082    
3 3                 5              14         41.87396         -87.62774        41.85809        -87.65107  12     41.858086 -87.651073
4 4                 5              15         41.87396         -87.62774        41.85645        -87.65647  19     41.856453 -87.656471
5 5                 5              16         41.87396         -87.62774        41.91033        -87.67252   7     41.910329 -87.672516
6 6                 5              17         41.87396         -87.62774        41.90332        -87.67273   5       41.90332 -87.67273
                thomas
1 41.87395806 -87.62773949
2 41.87395806 -87.62773949
3 41.87395806 -87.62773949
4 41.87395806 -87.62773949
5 41.87395806 -87.62773949
6 41.87395806 -87.62773949

Then I set about making an easier df for the function in the idea post, a la:

start<-c(counts[1:10,9])
dest<-c(counts[1:10,10])

I thought I might add in numbers into the function so I tagged on n (maybe not the best naming convention, but stick with me here).

n <- c(counts[1:10, 8])

then the route searching function:

leg <-function(start, dest){
     r<- route(from=start,to=dest,mode = c("bicycling"),structure = c("legs"))  
     c<- geom_leg(aes(x = startLon, y = startLat, xend = endLon, yend = endLat),
                  alpha = 2/4, size = 2, data = r, colour = 'blue') 

     return (c)
 }

base map:

a<-qmap('Chicago', zoom = 12, maptype="roadmap", color="bw") 

now the magic:

for (n in 1:10){
     #l<-leg(start[n], dest[n])  
     l<-leg(as.character(df[n,1]), as.character(df[n,2]))  

    a<-a+l
 }
a

This worked.

unfortunately when I tried to run it on a larger subset it would run for a little bit and then go:

Information from URL : http://maps.googleapis.com/maps/api/directions/json?   origin=41.88871604+-87.64444785&destination=41.87395806+-87.62773949&mode=bicycling&units=metric&alternatives=false&sensor=false
Error: (list) object cannot be coerced to type 'integer'

I understand from searching here and elsewhere that this can be due to Google gating api calls, and so tried adding in Sys.sleep(1), but that would break, so went to Sys.sleep(1.5) and frankly that still seems to. Even that is a pretty expensive call, given that for +55k rows you're looking at +23 hours of calls. My code was:

for (n in 1:30){
 #l<-leg(start[n], dest[n])  

 l<-leg(as.character(df[n,1]), as.character(df[n,2]))  
 Sys.sleep(1.5)     
a <- a + l
a}

this seemed to run but when I entered "a" I got:

Error in eval(expr, envir, enclos) : object 'startLon' not found

Finally as mentioned I'd like to visualize thicker lines for more used routes. typically I'd do this via the aes and doing something like:

geom_path(
aes(x = lon, y = lat),  colour = 'red', size = n/100,
data = df, lineend = 'round'
  )

so it would read column n and grant a size based on number of routes. for that to work here I need that number to bind to the directions route, so I wrote a second function like this:

leg <-function(start, dest, n){

 r<- route(from=start,to=dest,mode = c("bicycling"),structure = c("route"))  
 c<- geom_leg(aes(x = startLon, y = startLat, xend = endLon, yend = endLat),
              alpha = 2/4, size = n/10, data = r, colour = 'blue') 

 return (c)
}

for (n in 1:55704){
#l<-leg(start[n], dest[n])  

l<-leg(as.character(df[n,1]), as.character(df[n,2]), as.numeric(df[n,3]))  
Sys.sleep(1)       
a <- a+l       
  }

This ran for a minute and then died on the error:

Error: (list) object cannot be coerced to type 'integer'

but a shorter version got tantalizingly close:

for (n in 2:6){
#l<-leg(start[n], dest[n])  

l<-leg(as.character(df[n,1]), as.character(df[n,2]), as.numeric(df[n,3]))  
Sys.sleep(1)       
a <- a+l       
}

it worked, as far as I can tell, but nothing more than like 30. Sadly the longer version just kind of runs out. basically I think that if I can get past the error message I'm almost there, I just don't want to have to spend days running the query. All help and input welcome. thank you for your time.

ok, so after a lot of noodling and modifying the above I finally settled on the looping solution that works:

leg <-function(start, dest, n){

    r<- route(from=start,to=dest,mode = c("walking"),structure = c("route"))  
    c<- geom_path(aes(x = lon, y = lat),
             alpha = 2/4, size = as.numeric(n)/500, data = r, colour = 'blue') 
    Sys.sleep(runif(1, 3.0, 7.5))
    return (c)
}

a <- qmap('Chicago', zoom = 12, maptype = 'road', color="bw")

for (n in 101:200){
    l<-leg(as.character(df[n,1]), as.character(df[n,2]),as.character(df[n,3])) 

    a<-a+l
}

a

this worked fairly well. the only bumps were when it the google api would reject the call. after I added the random variable sys.sleep in there it worked without a hitch. That said, I still never tried more than 150 at a go (limited my mapping to a sample of the top 10% of routes for ease of visual and for function). Finally after some happy illustrator time I ended up with a good looking map. Thanks to the community for the interest and for providing the looping idea.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM