R JSONlite: Как справиться с ошибкой ниже?

Посмотрите код R ниже, я использую пакет JSONlite для очистки данных с веб-сайта:

library(jsonlite)
    url <- "http://fantasy.premierleague.com/web/api/elements/"
    seasonsdata <- data.frame(matrix(NA,nrow=1,ncol=20))
    seasonsdata <- seasonsdata[-1,]
    fetchData <- function(i) {res <- try(a <- fromJSON(paste0(url,i)))
    if(!inherits(res,"try-error")) {b<-data.frame(a[1],a[20],a[21],as.data.frame(a$season_history))}}

    seasonsdata <- lapply(1:696, fetchData)
    seasonsdata <-do.call(rbind,lapply(seasonsdata,data.frame,stringsAsFactors=FALSE))

Код работает нормально для "я" до 10, по крайней мере, я получаю желаемый результат. Однако, когда я увеличиваю "i" до 696, я получаю ошибку:

Error in data.frame(a[1], a[20], a[21], as.data.frame(a$season_history)) : 
  arguments imply differing number of rows: 1, 0

Любой совет?

1 ответ

Если a$season_history пуст (страница 57 является примером), то когда вы делаете data.frame(a[1], a[20], a[21], as.data.frame(a$season_history)) первые 3 элемента имеют одну строку (они являются скалярами), а последний элемент имеет нулевые строки. В вашей функции вы можете сначала проверить, если a$season_history есть. Если это не так, вы можете создать ряд NAs на своих местах.

Однако есть еще одна проблема с вашим кодом, о которой вы, возможно, еще не знаете. Не каждая страница до 696 существует, и вы получаете ошибку 404 при попытке извлечь из нее данные. Я добавил несколько шагов, чтобы удалить эти страницы, прежде чем делать финальный do.call(rbind, ...) шаг.

library(jsonlite)
url <- "http://fantasy.premierleague.com/web/api/elements/"
seasonsdata <- data.frame(matrix(NA, nrow = 1, ncol = 20))
seasonsdata <- seasonsdata[-1, ]
fetchData <- function(i) {
  res <- try(a <- fromJSON(paste0(url, i)))
  if (!inherits(res, "try-error")) {
    if (nrow(as.data.frame(a$season_history)) == 0) {
      b <- data.frame(a[1], a[20], a[21], as.data.frame(matrix(NA, ncol = 17)))
    } else {
      b <- data.frame(a[1], a[20], a[21], as.data.frame(a$season_history))
    }
  }
}

seasonsdata <- lapply(1:696, fetchData)
seasonsdata <- seasonsdata[!sapply(seasonsdata, is.null)]
seasonsdata <- seasonsdata[sapply(seasonsdata, is.data.frame)]
seasonsdata <- do.call(rbind,lapply(seasonsdata, data.frame, stringsAsFactors = FALSE))
Другие вопросы по тегам