Удаление элементов из списка во время итерации по нему в R

#r #loops

#r #циклы

Вопрос:

У меня есть фрейм данных с наблюдениями на YouTube video_ids . При использовании в вызове API эти идентификаторы позволяют мне извлекать данные по определенным видео, которые я использую для обогащения моего набора данных.

Сначала я создал список уникальных идентификаторов video_ids с помощью приведенного ниже сценария. Это возвращает большой список из 6350 уникальных элементов.

 video_ids <- list();
index <- 1
for(i in unique(df$video_id)){
  video_ids[[index]] <- list(
    video_id = i
  )
  index <- index   1
}
  

Документация API запрашивает разделенный запятыми список идентификаторов видео. Я сделал это, используя unlist(video_ids) which возвращает большой вектор. Я не могу использовать этот вектор в вызове API, потому что он слишком длинный.

Максимальное количество идентификаторов, которые я могу обработать за один вызов API, равно 50.

 library(httr)
api_key = "xxxx"
process_ids = unlist(video_ids[1:50]) #pass the first 50 elements of the video_ids list
url <- modify_url("https://www.googleapis.com/youtube/v3/videos", 
                  query = list(
                    "part" = "snippet",
                    "id" = paste(process_ids, collapse=","),
                    "key" = api_key)
)
output <- content(GET(url), as = "parsed", type = "application/json")

  

Каков наилучший подход для этого в R? Могу ли я перебирать свой список из 6350 элементов по 50 элементов в каждом цикле, удаляя эти элементы из списка по завершении цикла?

Мой текущий сценарий, приведенный ниже, перебирает каждый идентификатор видео в списке и извлекает нужные мне данные из выходных данных ответа API. Это работает, но очень медленно и требует много циклов / вызовов API. (6350 циклов). Это не может быть наиболее эффективным способом решения этой проблемы.

 result <- list();
index <- 1
for (id in video_ids) {
  api_key = "xxxx"
  url <- modify_url("https://www.googleapis.com/youtube/v3/videos", 
                    query = list(
                      "part" = "snippet",
                      "id" = paste(id, collapse=","),
                      "key" = api_key)
  )
  output <- content(GET(url), as = "parsed", type = "application/json")
  
  #Adds what I need from the output to a list called result
  for(t in output$items){
    result[[index]] <- list(
      video_id = t$id,
      channel_id = t$snippet$channelId
    )
  }
  index <- index   1
}
  

Ответ №1:

Вы можете попробовать следующее :

Разделите идентификатор видео на каждые 50 значений и передайте его в API.

 vec = unlist(video_ids)
result <- lapply(split(vec, ceiling(seq_along(vec)/50)), function(x) {
            url <- modify_url("https://www.googleapis.com/youtube/v3/videos", 
                             query = list(
                             "part" = "snippet",
                             "id" = paste(x, collapse=","),
                             "key" = api_key))
  content(GET(url), as = "parsed", type = "application/json")
})