2017-10-17 98 views
0

我试图运行结果中的URL列表运行查询结果使用GET函数从环

URL标准

lon <- as.list(seq(-124.4531, -68.02734, by=5.9180)) 
lat <- as.list(seq(25.7998, 49.0090, by=5.6667)) 
z <- expand.grid(lon,lat) 
z <- as.data.frame(cbind("lon" = unlist(z$Var1), "lat" = unlist(z$Var2))) 
n = dim(z)[1] 

创建URL列表

for(i in 1:n) { 
    for(j in 1:n) { 
    URL<- paste0("https://maps.googleapis.com/maps/api/place/radarsearch/json?location=", as.character(z$lat[j]), ",", as.character(z$lon[i]),     "&radius=50000&name=MetroPCS&key=key") 

    print(URL) 
    } 
} 

使用GET功能运行URL列表

loop<-function(URL){ 
    res<-GET("URL") 
    jasonAnse<-contnet(res,"text") 
    myDataframe<- jsonlite::fromJSON(content(res,"text")) 
} 

myDataframe 

能够运行所有记录,但只保存最后一个记录

但它看起来像GET功能只能运行最后一条记录。不知道它是否与循环或GET()函数有关。

+0

您是否在双''''循环之间和之后查看了'URL'的值? 'print'-ing给控制台带来了一些东西,这对于一个“感觉良好”的时刻来说真的只是一件好事,但对后续代码却没有任何作用。你需要捕获它,也许通过预先分配一个大的矢量(不推荐)或者使用像'mapply'这样的东西。 – r2evans

+0

也许'URL < - mapply(sprintf,list(“https://maps.googleapis.com/maps/api/place/radarsearch/json?location=%s,%s”),z [,1],z [,2])'是一个开始? (我意识到在位置之后还有更多的字符串,我只是在这里开始......如果您不熟悉,请查看['?sprintf'](https://stat.ethz.ch/ R-manual/R-devel/library/base/html/sprintf.html)。) – r2evans

+0

@ r2evans,谢谢。 -mapply-在生成URL列表方面效果很好,但GET()循环似乎仍然只能运行最后的结果。不确定是否要执行GET()函数? – jessiez

回答

0

每当我看到一个说“1或更多”的问题时,我倾向于考虑一次做某件事,然后迭代向量或列表中的所有项目。你开始以这种方式思考,但在你的循环中,你每次分配而不是URL,只保存最后一个。即使你保存了所有的URL,但是,GET一次只能检索一个,所以你也需要重复这个函数。

这个演示大多是概念,没有真正的证明它的工作原理。由于您在问题中包含了实际的API密钥,因此它已经用尽。 (你可能想从问题中删除它)。无论如何,我对将这些函数应用于一系列事物的概念有点自信,所以尽管我没有证实你得到了一个巨大的data.frame,也许我会幸运的。

z <- expand.grid(lon = seq(-124.4531, -68.02734, by=5.9180), 
       lat = seq(25.7998, 49.0090, by=5.6667)) 
head(z) 
#   lon  lat 
# 1 -124.4531 25.7998 
# 2 -118.5351 25.7998 
# 3 -112.6171 25.7998 
# 4 -106.6991 25.7998 
# 5 -100.7811 25.7998 
# 6 -94.8631 25.7998 

mapply(和Map)通过施加从载体/列表1以上参数的单一功能的工作(第一个参数)。在某些语言中,它被认为是“拉大论点”。试想一下:

mapply(function(x,y,z) x+y-z, 
     c(1,2,3,4), c(5,6,7,8), c(9,10,11,12)) 

第一次调用匿名函数将执行1+5-9;第二,2+6-10;等有进一步的技巧,利用这一点,但回头看你的问题:

URLs <- mapply(sprintf, 
       list("https://maps.googleapis.com/maps/api/place/radarsearch/json?location=%s,%s&radius=50000&name=MetroPCS&key=AIzaSyA3u4HwTGiUsHP7FNUKkjbYcHHe1xFBDTU"), 
       z$lat, z$lon) 

编辑:我以前有z$latz$lon逆转mapply内,固定)

功能sprintf接受任意数量的参数:第一个始终是格式化字符串,第二个和以后(如果有的话)始终是填充格式化字符串的参数/对象。所述list("htt...")参数只是提供了参数的sprintf每个呼叫,所以函数调用细分为:

sprintf("https...", z$lon[1], z$lon[2]) 
sprintf("https...", z$lon[2], z$lon[2]) 
# ... 
sprintf("https...", z$lon[50], z$lon[50]) 

这些呼叫被包裹回一个character矢量,长度为50。

(URLs <- head(URLs)) # doing this for a simpler demo, since I don't need all 50 
# [1] "https://maps.googleapis.com/maps/api/place/radarsearch/json?location=-124.4531,25.7998&radius=50000&name=MetroPCS&key=AIzaSyA3u4HwTGiUsHP7FNUKkjbYcHHe1xFBDTU" 
# [2] "https://maps.googleapis.com/maps/api/place/radarsearch/json?location=-118.5351,25.7998&radius=50000&name=MetroPCS&key=AIzaSyA3u4HwTGiUsHP7FNUKkjbYcHHe1xFBDTU" 
# [3] "https://maps.googleapis.com/maps/api/place/radarsearch/json?location=-112.6171,25.7998&radius=50000&name=MetroPCS&key=AIzaSyA3u4HwTGiUsHP7FNUKkjbYcHHe1xFBDTU" 
# [4] "https://maps.googleapis.com/maps/api/place/radarsearch/json?location=-106.6991,25.7998&radius=50000&name=MetroPCS&key=AIzaSyA3u4HwTGiUsHP7FNUKkjbYcHHe1xFBDTU" 
# [5] "https://maps.googleapis.com/maps/api/place/radarsearch/json?location=-100.7811,25.7998&radius=50000&name=MetroPCS&key=AIzaSyA3u4HwTGiUsHP7FNUKkjbYcHHe1xFBDTU" 
# [6] "https://maps.googleapis.com/maps/api/place/radarsearch/json?location=-94.8631,25.7998&radius=50000&name=MetroPCS&key=AIzaSyA3u4HwTGiUsHP7FNUKkjbYcHHe1xFBDTU" 

我们仍然有“1个或多个”列表中,这样我们就可以继续使用lapply逻辑:

HTMLs <- lapply(URLs, GET) 
HTMLs[1] 
# [[1]] 
# Response [https://maps.googleapis.com/maps/api/place/radarsearch/json?location=-124.4531,25.7998&radius=50000&name=MetroPCS] 
# Date: 2017-10-18 03:23 
# Status: 200 
# Content-Type: application/json; charset=UTF-8 
# Size: 141 B 
# { 
# "error_message" : "This service requires an API key.", 
# "html_attributions" : [], 
# "results" : [], 
# "status" : "REQUEST_DENIED" 
# } 

在这种情况下,我得到一个失败(这将削弱我能做什么以后),但是这个输出告诉你,你的HTMLs变量应该是50的长度,每个都是这样的。

继续,虽然从这里开始它没有经过测试。我相信你已经测试过这个功能,一次只能使用一个URL。

contents <- lapply(HTMLs, content, "text") 
myDataFrames <- lapply(contents, jsonlite::fromJSON) 

这最后一个应该是data.frame秒的名单,这是伟大的!我通常做的与此两种情况之一:如果我可以轻松地将它们合并成一个单一的data.frame,那么怎么办?(rbind?):

myDataFrame <- do.call(rbind.data.frame, c(myDataFrames, list(stringsAsFactors = FALSE))) 

(采用stringsAsFactors大多是风格,但显示如何添加(如果你需要它们)。

但是,如果保持它们分开是有益的(也许它们不是同构的结构),那么在列表上操作(重复使用lapply或相关)仍然是非常容易的。

一个可以证明通过单个调用这个简化了一下:

myDataFrames <- lapply(URLs, function(u) { 
    html <- GET(u) 
    cont <- cont(html, "text") 
    jsonlite::fromJSON(cont) 
}) 

,这是没有错的。但是,特别是在开发过程中,保留不同对象的中间列表可能是有益的。

+0

lapply中的get()不起作用,虽然它显示响应但结果为空。如果get()函数工作,结果应该有几何/位置/经度信息。 – jessiez

+0

你使用'get'还是'GET'?它们都存在,目的截然不同。另外,你确定这是否适用于单个URL(不使用'lapply')?只是检查。 – r2evans

+0

使用GET,抱歉是错字。 GET工作,只有一个例如:U < - “https://maps.googleapis.com/maps/api/place/radarsearch/json?location=31.1334,-81。3071&半径= 50000&名称= MetroPCS的&键= AIzaSyA3u4HwTGiUsHP7FNUKkjbYcHHe1xFBDTU” RES <-GET(U) jsonAnsw <-content(RES, “文本”) myDataframe < - jsonlite :: fromJSON(含量(RES, “文本”)) – jessiez