R:使用ggmap映射多个路由 [英] R: Mapping multiple Routes using ggmap

查看:184
本文介绍了R:使用ggmap映射多个路由的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在试图做出不同的可爱的流动数据可视化这个星期有一段时间,但在最后的实施过程中不断遇到障碍。



以下是数据集我'使用。我已经将它融入了一个框架,其中包含我想要显示的三个关键信息:起始位置,结束位置和旅行次数。



我最近用了,但两个在两个项目上遇到了障碍:

1)使行的大小更改基于关于旅行次数
2)让google api允许我调用这么多行(我的数据集中有55,704)。

counts是我的完整df的名字,看起来像这样:

 头(计数)
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

然后我开始制作一个

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

我可能会在数字中加入这样的功能在n上标记(可能不是最好的命名约定,但坚持在这里)。

  n < -  c(counts [ 

然后路径搜索功能:

  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,color ='blue')

return(c)
}

底图:

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

现在神奇:

  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

这有效。



不幸的是,当我试图在一个更大的子集上运行它时,它会运行一段时间,然后转到:

 来自网址的信息:http://maps.googleapis.com/maps/api/directions/json?原始= 41.88871604 + -87.64444785&目的地= 41.87395806 + -87.62773949& mode = bicycling& units = metric& alternatives = false& sensor = false 
错误:(列表)对象不能被强制键入'integer'

我从这里和其他地方搜索得知,这可能是由于谷歌门户API调用,因此尝试添加在Sys.sleep(1)中,但那会破坏,所以去了Sys.sleep(1.5),坦率地说,似乎仍然如此。即使这是一个非常昂贵的电话,考虑到+ 55k行你正在查看+23小时的电话。我的代码是:

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

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

运行,但是当我输入a时,我得到了:

pre $ eval(expr,envir,enclos)中的错误:object'startLon '找不到

最后提到我希望将更粗的线显示为更多使用的路线。通常我会通过aes执行此操作并执行如下操作:

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

,所以它会读取列n并根据路由数量授予大小。为了在这里工作,我需要这个数字绑定到方向路线,所以我写了第二个函数,如下所示:

  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,color ='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
>

运行了一分钟,然后死于错误:

 错误: (list)对象不能被强制键入'integer'

但是更短的版本变得非常接近:

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

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

据我所知,它的工作原理很简单,只不过是30而已。可悲的是,更长的版本只是用完了。基本上我认为,如果我可以通过错误消息我几乎在那里,我只是不想花费几天运行查询。所有的帮助和输入欢迎。谢谢你的时间。

好的,所以经过大量的修改和修改上面的内容之后,我终于决定了循环解决方案:

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

r< - 路由(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,color ='blue')
Sys.sleep(runif(1,3.0,7.5))
返回(c)
}

a < - qmap('Chicago',zoom = 12,maptype ='road',color =bw)
$ b $ (d为[n,2]),as.character(df [n,2]),as.character(df [n ,3]))

a< -a + l
}

a

这工作得很好。唯一的颠簸是当谷歌API会拒绝这个电话。在我添加了随机变量sys.sleep之后,它没有任何问题。也就是说,我还是从来没有尝试过超过150次(为了便于视觉和功能,我将其映射到前10%路线的样本)。最后,在一些快乐的插画师时间结束后,我看到了一张好看的地图。感谢社区的兴趣和提供循环的想法。

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.

这篇关于R:使用ggmap映射多个路由的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆