Search code examples
rfunctionellipsis

How to see if ... ellipses in R contains a certain argument?


I'm writing a wrapper for the YouTube Analytics API, and have created a function as follows:

yt_request <- function(dimensions = NULL, metrics = NULL, sort = NULL,
                    maxResults = NULL, filtr = NULL, startDate = Sys.Date() - 30,
                                endDate = Sys.Date(), token) {
  
  url <- paste0("https://youtubeanalytics.googleapis.com/v2/reports?",
                "&ids=channel%3D%3DMINE",
                "&startDate=", startDate, 
                "&endDate=", endDate)
  
  if(!is.null(dimensions)) url <- paste0(url, "&dimensions=", dimensions)
  if(!is.null(metrics))    url <- paste0(url, "&metrics=", metrics)
  if(!is.null(sort))       url <- paste0(url, "&sort=", sort)
  if(!is.null(maxResults)) url <- paste0(url, "&maxResults=", maxResults)
  if(!is.null(filtr))      url <- paste0(url, "&filters=", filtr)
  
  r <- GET(url, token)
  return(r)
}

This is meant to just be a flexible but not the most friendly of functions because I want to have wrapper functions that will contain yt_request() that will be much more user friendly. For example:

top_videos <- function(...) {
  dim <- "video"
  met <- "views,averageViewDuration"
  maxRes <- 10

  temp <- yt_request(dimensions = dim, metrics = met, maxResults = maxRes, token = myToken)
  return(temp)
}

Which so far works fine and dandy, but I also want potential users to have a little flexibility with the results. For example, if they want to have maxResults <- 20 instead of 10 or they want different metrics than the ones I specify, I want them to be able to pass their own arguments in the ... of top_videos(...).

How can I do a check if someone passes an argument in the ellipsis? If they pass a metric, I want it to override the default I specify, otherwise, go with the default.

EDIT

To help clarify, I'm hoping that when the user decides to use the function, they could just write something like top_videos(maxResults = 20) and the function would ignore the line maxRes <- 10 and in the yt_request() function would assign maxResults = 20 instead of 10


Solution

  • We can capture the ... in a list and convert the whole elements to a key/value pair. Then, extract the elements based on the name. If we are not passing that particular named element, it will return NULL. We make use of this behavior of NULL to concatenate with the default value of 10 in maxRes and select the first element ([1]) so that if it is NULL, the default 10 is selected, or else the value passed will be selected. Likewise, do this on all those objects that the OP wanted to override

    top_videos <- function(...) {
    
        nm1 <- list(...)
          lst1 <- as.list(nm1)
          
          dim <- c(lst1[["dimensions"]], "video")[1]
           met <- c(lst1[["metrics"]], "views,averageViewDuration")[1]
           maxRes <- c(lst1[['maxResults']], 10)[1]
           
           #temp <- yt_request(dimensions = dim, 
                metrics = met, maxResults = maxRes, token = myToken)
           #temp
           maxRes
          }
    

    -testing

    top_videos(maxResults = 20)
    #[1] 20
          
      top_videos(hello = 5)
    #[1] 10