Krank
Krank

Reputation: 161

R loops with JSON API Source

I'm trying to get data for books prices from API (http://www.knigoed.info/api-prices.html) based on ISBN.

The idea is to submit vector of ISBNs to the function to get a data frame with all available info (or at least Data.Frame with prices from different vendors)

isbns<- c("9785170922789", "9785170804801", "9785699834174", "9785699717255", "9785170869237")


getISBNprice <- function(ISBN, source="http://www.knigoed.info/api/Prices?code=") {
        pathA <- source
        for (i in 1:length(ISBN)) {

                ISB <- ISBN[i]
                AAA <- paste(pathA, ISB, "&sortPrice=DESC&country=RU", sep="")
                document <- fromJSON(AAA, flatten = FALSE)

                dfp <- document$prices
                dfp <- cbind(dfp,ISB ) 
                # dfp <- cbind(dfp,BookID=document$bookId) 
                # dfp <- cbind(dfp,Title=document$title) 
                # dfp <- cbind(dfp,Author=document$author) 
                # dfp <- cbind(dfp,Publisher=document$publisher)
                # dfp <- cbind(dfp,Series=document$series)
                # dfp <- cbind(dfp,Picture=document$picture)

                if (!exists("AAAA")) {AAAA<- dfp} else {bind_rows(AAAA, dfp) }
        }

        AAAA
}        

But the function returns error: 1. In bind_rows_(x, .id) : Unequal factor levels: coercing to character 2: In bind_rows_(x, .id) : Unequal factor levels: coercing to character 3: In bind_rows_(x, .id) : Unequal factor levels: coercing to character 4: In bind_rows_(x, .id) : Unequal factor levels: coercing to character

Upvotes: 0

Views: 431

Answers (1)

alistaire
alistaire

Reputation: 43354

It's easiest make a list from the start, which will make simplifying later easier. The purrr package can make working with lists much easier, though the usages here can be replaced with base's lapply and mapply/Map if you prefer.

library(purrr)

# Paste is vectorized, so make a list of URLs all at once. 
# `httr` can make a URL out of a list of named parameters, if it's more convenient.
results <- paste0("http://www.knigoed.info/api/Prices?code=", 
                  isbns, 
                  "&sortPrice=DESC&country=RU") %>% 
    # Iterate over vector of URLs, using fromJSON to pull and parse the request.
    # map, like lapply, will put the results into a list. 
    map(jsonlite::fromJSON, flatten = FALSE)

            # Grab "prices" element of each top-level list element
results %>% map('prices') %>% 
    # Iterate in parallel (like mapply/Map) over prices and isbns, making a data.frame of
    # each. map2_df will coerce the resulting list of data.frames to a single data.frame.
    map2_df(isbns, ~data.frame(isbn = .y, .x, stringsAsFactors = FALSE)) %>%
    # For pretty printing
    tibble::as_data_frame()

## # A tibble: 36 x 10
##             isbn shopId       name      domain
##            <chr>  <chr>      <chr>       <chr>
## 1  9785170922789     29    Магистр    booka.ru
## 2  9785170922789      3   Лабиринт labirint.ru
## 3  9785170922789     20  LitRes.ru   litres.ru
## 4  9785170804801     29    Магистр    booka.ru
## 5  9785170804801      2    Read.ru     read.ru
## 6  9785170804801      3   Лабиринт labirint.ru
## 7  9785170804801     63      Эксмо    eksmo.ru
## 8  9785170804801      1    OZON.ru     ozon.ru
## 9  9785170804801      4 My-shop.ru  my-shop.ru
## 10 9785170804801      1    OZON.ru     ozon.ru
## # ... with 26 more rows, and 6 more variables: url <chr>, available <lgl>, downloadable <lgl>,
## #   priceValue <dbl>, priceSuffix <chr>, year <int>

Upvotes: 3

Related Questions