2017-10-17 36 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