Как я могу зациклить функцию jsonlite на фрейме данных URL-адресов?
Я пытаюсь запустить функцию jsonlite на наборе URL-адресов API, которые я накопил. В частности, у меня есть фрейм данных url_df, в котором есть столбец с именем URL с 162800 строками URL-адресов API. Когда я пишу сценарий и вручную вставляю каждый URL-адрес, он работает отлично. Это сценарий, который я использую для его ручного запуска по одному URL-адресу за раз:
May28 <- 'https://example.example.com/example'.
May28 <- httr::GET(May28)
May28 <- httr::content(May28, as = 'text')
May28 <- jsonlite::fromJSON(May28)
dplyr::glimpse(May28)
May28 <- as.data.frame(May28)
write.table(May28, file="May28.csv", sep=",")
Однако, поскольку у меня есть более 100 тыс. Строк URL-адресов API, я хотел создать функцию цикла, которая повторяет указанную выше функцию для каждой строки (каждого URL-адреса API) в URL-адресе столбца, чтобы мне не приходилось вручную вырезать и вставьте каждый URL в скрипт более 100 тысяч раз. Поэтому я сохранил эту информацию во фрейме данных под названием "url_df" и попытался ввести следующий код:
j <- 1
for (j in 1:nrow(url_df)){
url <- url_df$URL[[j]] %>%
getdata <- GET(url) %>%
rawdata <- httr::content(getdata, as='text') %>%
data <- jsonlite::fromJSON(rawdata)
data_df <- as.data.frame(data)
print(j)
j <- j+1
Sys.sleep(0.5)
}
Почему-то не запускается. Одна из полученных мной ошибок была: Ошибка в jsonlite::fromJSON(rawdata): объект rawdata не найден.
Одно предостережение, которое может быть важным: каждый URL-адрес API не возвращает только одно значение точки данных (например, 1). Вместо этого он возвращает список значений (например, воскресенье, 1, вторник, 2 и т. Д.).
Есть идеи о том, почему это может происходить или как я могу это преодолеть?
После решения этой первой проблемы я хотел бы по возможности связать все собранные мной данные...
Спасибо!!!
2 ответа
Вы пробовали без %>%
? Кроме того, вы можете попробовать воспроизводимый пример с фиктивными URL-адресами API, такими как https://jsonplaceholder.typicode.com/todos/1
Причина for
сбой цикла происходит из-за того, что у вас есть недопустимые или проблемные URL-адреса.
Посмотрите, может ли что-то подобное решить вашу проблему:
library(tidyverse)
# Function to download - it takes two inputs: (1) url and (2) save file name
dl_my_url <- function(url_address, file_name_to_save){
x <- httr::GET(url_address)
y <- httr::content(x, as = 'text')
z <- jsonlite::fromJSON(z)
print(dplyr::glimpse(z))
output <- as.data.frame(z)
write.table(output, file = file_name_to_save, sep=",")
}
# make the function safe in case some url fails
safe_dl_my_url <- safely(dl_my_url)
# Run the function (make sure you create a save name for each url)
url_result <- map2(urldf$address, urldf$file_name_to_save, ~safe_dl_my_url(.x, .y))
# To get your results
map(url_result, "result") %>% bind_rows() # or bind_cols which ever works for you
# Check what is failing
map(url_result, "error")