Как я могу l oop функцию jsonlite в фрейме данных URL-адресов? - PullRequest
2 голосов
/ 29 мая 2020

Я пытаюсь запустить функцию 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 тыс. Строк API-адресов до go, я хотел создать al oop функция, которая повторяет вышеуказанную функцию для каждой строки (каждого 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 :: from JSON (rawdata): объект rawdata не найден.

Одно важное замечание: каждый URL-адрес API не возвращает только 1 значение точки данных (например, 1). Вместо этого он возвращает список значений (например, воскресенье, 1, вторник, 2 и т. Д. c).

Есть идеи, почему это может происходить или как я могу это преодолеть?

Решив эту первую проблему, я хотел бы затем связать все собранные мной данные, если это возможно ...

Спасибо !!!

Ответы [ 2 ]

0 голосов
/ 29 мая 2020

Причина ошибки for l oop в том, что у вас есть недействительные или проблемные c 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")
0 голосов
/ 29 мая 2020

Пробовали без %>%? Кроме того, вы можете попробовать воспроизводимый пример с фиктивными URL-адресами API, такими как https://jsonplaceholder.typicode.com/todos/1

...