【问题标题】:Loop function not returning right result in R循环函数没有在 R 中返回正确的结果
【发布时间】:2021-03-22 14:31:39
【问题描述】:

我在下面创建了一个函数,用于从 places api 中获取谷歌数据。输入是带有 api 键的 google url,应该返回搜索地点的数据集。但由于某种原因,数据集只返回相同的数据迭代(即一遍又一遍的相同位置)。如果我手动逐行运行它可以正常工作,所以我有点卡住了。我认为可能与返回值有关。

所以该函数调用 api 并创建一个数据集(ds),然后抓取下一页键(页面令牌),因为 google 一次只发送 20 个值。然后它运行循环,将下一页键添加到 URL 并将其放入新数据集 (ds_new),然后通过 rbind(ds,ds_new) 将该数据与旧数据组合。这个循环一直持续到下一页 key == NULL 或运行十次迭代。然后返回数据集(ds)

任何提示或帮助将不胜感激。

google_key_places <- ###############
search_type <- "bar"
lat_long <- "-27.502870962086018,153.03244147954413"
radius <- "6000"    #in meters 
pagetoken <- ""
url <- paste0("https://maps.googleapis.com/maps/api/place/nearbysearch/json?",
              "location=",lat_long,
              "&radius=",radius,
              "&type=",search_type,
              "&key=",google_key_places)
get_google_places <- function(url){
  
    doc <- getURL(url)                       # Grabs the URL data
    x <- jsonlite::fromJSON(doc)
    ds <- cbind(x$results$geometry$location, # lat and long
                x$results$name,              # Name of Business
                x$results$vicinity,          # Address of Business
                x$results$price_level,       # Price Level (1 Cheapest - 5 Most Expensive)
                x$results$rating,            # Google Ratings
                x$results$user_ratings_total,# Total User Ratings
                x$results$place_id)          # Google ID Code
    pagetoken <- x$next_page_token
    
    for (i in 1:10){ 
      url_new <- paste0(url,"&pagetoken=",pagetoken)
      doc <- getURL(url_new)
      x <- jsonlite::fromJSON(doc)
      ds_new <- cbind(x$results$geometry$location, # lat and long
                  x$results$name,              # Name of Business
                  x$results$vicinity,          # Address of Business
                  x$results$price_level,       # Price Level (1 Cheapest - 5 Most Expensive)
                  x$results$rating,            # Google Ratings
                  x$results$user_ratings_total,# Total User Ratings
                  x$results$place_id)          # Google ID Code
      pagetoken <- x$next_page_token
      ds <- rbind(ds,ds_new)
      if (is.null(pagetoken)){
        return(ds)
      }
    }
    
    return(ds)
  
}

【问题讨论】:

  • 我喜欢@Pake 对一些建议的回答,但我不知道这里有足够的信息让我们这些没有 google api 密钥的人能够确定发生了什么.更详细地查看响应可能会有所帮助。例如,在循环中,发布url_newstr(ds_new)pagetoken 的输出,然后在循环的下一次迭代中同样如此。 (我认为不需要超过两个。)

标签: r function loops google-places-api google-places


【解决方案1】:

我会尝试这些通用步骤:

  1. 列一个清单。我们首先简单地将列表命名为对您有意义的名称:

    google_stuff&lt;-list()

  2. 接下来,在定义输出时,在循环中使用[[]]。本质上,您在google_stuff 中为您的 10 个循环中的每一个创建一个列表项。因此,在基本形式中,您现在将拥有:

    google_stuff<-list()
    for (i in 1:10){
    url_new <- paste0(url,"&pagetoken=",pagetoken)
    doc <- getURL(url_new)
    x <- jsonlite::fromJSON(doc)
    ds_new <- cbind(x$results$geometry$location, # lat and long
               x$results$name,              # Name of Business
               x$results$vicinity,          # Address of Business
               x$results$price_level,       # Price Level (1 Cheapest - 5 Most 
                                                              #Expensive)
               x$results$rating,            # Google Ratings
               x$results$user_ratings_total,# Total User Ratings
                x$results$place_id)          # Google ID Code
     pagetoken <- x$next_page_token
    
    
     google_stuff[[i]]<-ds_new
    

    }

  3. 最后,您可以使用dplyr::bind_rows(google_stuff,ds) 获得一个包含您提取的所有数据的漂亮数据框。

    all_my_google_stuff<-dplyr::bind_rows(google_stuff,ds)
    

【讨论】:

  • 因为之前没有使用过dplyr,所以bind_rows 的替代品是do.call(rbind, google_stuff)。请注意,这需要引入第一个 ds,因为这里的代码就在 ds_new 上。
  • 无论如何,我建议您在通话前添加dplyr::,或在前面添加library(dplyr),因为OP 中既没有建议也没有在您的答案中明确指出。
猜你喜欢
  • 2021-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-27
相关资源
最近更新 更多