Векторизованная операция в R вызывает проблемы с пользовательской функцией

#r

#r

Вопрос:

Я выписываю некоторые функции для управления запасами. Недавно я захотел добавить «столбец URL-адреса фотографии» в свою электронную таблицу с помощью API, который я успешно использовал при первоначальном создании своего инвентаря. Заголовок моей электронной таблицы выглядит следующим образом:

 SKU | NAME | OTHER STUFF
  

У меня есть getProductInfo функция, которая возвращает список информации о продукте из API, который я вызываю.

 getProductInfo<- function(barcode) {
    #Input UPC
    #Output List of product info
    CallAPI(barcode)
    Process API return, remove garbage
    return(info)
}

  

Я создал новую функцию, которая принимает мой инвентарь csv в качестве входных данных и пытается добавить новый столбец с URL-адресом фотографии продукта.

 get_photo_url_from_product_info_output <- function(in_list){
  #Input GetProductInfo Output. Returns Photo URL, or nothing if
  #it doesn't exist
  if(in_list$DisplayStockPhotos == TRUE){
    return(in_list$StockPhotoURL)
  } else {
    return("")
  }
}

add_Photo_URL <- function(in_csv){
  #Input CSV data frame, appends photourl column
  #Requires SKU (UPC) assumes no photourl column

  out_csv <- mutate(in_csv, photo =
                  get_photo_url_from_product_info_output(
                    getProductInfo(SKU)
                    )
                )
}
  
  return (out_csv)
}

#Call it
new <- add_Photo_URL(old)
  

Я думал, что R просто введет артикул из строки и пропустит его через двойной вызов функции «как есть», а векторизованная функция mutate DPLYR просто векторизирует его. К сожалению, я сталкивался со всевозможными проблемами, которые я не мог понять. В конце концов я понял, что вызов API завершается сбоем, потому SKU что все поле было перепутано при его передаче. Я ввел точку останова и обнаружил, что она не просто передает SKU, а вместо этого весь список (я думаю?) SKU. Каждая строка сразу. Что-то вроде этого:

 #Variable 'barcode' inside getProductInfo function contains:
 [1] 7.869368e 11 1.438175e 10 1.256983e 10 2.454357e 10 3.139814e 10 1.256983e 10 1.313260e 10 4.339643e 10 2.454328e 10
 [10] 1.313243e 10 6.839046e 11 2.454367e 10 2.454363e 10 2.454367e 10 2.454348e 10 8.418870e 11 2.519211e 10 2.454375e 10
 [19] 2.454381e 10 2.454381e 10 2.454383e 10 2.454384e 10 7.869368e 11 2.454370e 10 2.454390e 10 1.913290e 11 2.454397e 10
 [28] 2.454399e 10 2.519202e 10 2.519205e 10 7.742121e 11 8.839291e 11 8.539116e 10 2.519211e 10 2.519211e 10 2.519211e 10
  

Очевидно, что моя начальная getProductInfo функция не может справиться с этим, поэтому она выйдет из строя.
Как я должен изменить свой код, будь то при вводе или вызове API, чтобы избежать этой проблемы с векторизованной операцией?

Ответ №1:

Ну, это не совсем элегантно, но это работает.

Я понял, что мне нужно использовать lapply, что обычно не является моей сильной стороной. Изначально я пытался вложить их следующим образом:

 lapply(SKU, get_photo_url_from_product_info_output(getProductInfo())
  

Но это не сработало. Итак, я только что придумал блестящую идею создания другой функции

 get_photo_url_from_sku <- function(barcode){
  return(get_photo_url_from_product_info_output(getProductInfo(barcode)))
}
  

Вызовите это в lapply:

 out_csv<- mutate(in_csv, photocolumn = lapply(SKU, get_photo_url_from_sku))
  

И это отлично работает. Моя скорость ограничена только моими вызовами API.