Remi
Remi

Reputation: 1111

R: write function with optional arguments

I m trying to write a function that build an API request. The difficulty: I want to use optinal arguments inside the function, and build the API request according to the presence of these optional arguments. Example:

space <- "earth"
start_date <- "2018-10"
end_date <- "2018-11"
optionalArgument1 <- "America"
optionalArgument2 <- "people"
optionalArgument3 <- "size"
optionalArgument4 <- "ocean"

myfunction <- function(space, start_date, end_date, optionalArgument1, optionalArgument2, optionalArgument3, optionalArgument4){

              api_request <- paste0("https://myapi.com/getData?hello",

                    #NEEDED
                    "&space={s:'", space,"'}",
                    "&period={M:{start:'",start_date,"',end:'",end_date,"'}}",

                    #OPTIONAL
                    "&filter={",
                        "SMALL_filter1:{$sf1:'",optionalArgument1,"'},",
                        "SMALL_filter2:{$sf2:'",optionalArgument2,"'},",
                        "SMALL_filter3:{$sf3:'",optionalArgument3,"'}",
                    "}",

                    "&segment=",optionalArgument4

              )

              return(api_request)    
}

My goal is to allow the function to deliver the api_request, wether a user gives 1, 2, 3 or the 4 optional arguments.

For exemple:

myfunction(space, start_date, end_date, optionalArgument1, optionalArgument4)

Should return something like this:

[1] https://myapi.com/getData?hello&space={s:'earth'}&period={M:{start:'2018-10'end:'2018-11'}}&filter={SMALL_filter1:{$sf1:'America'}}&segment="ocean

An other example:

myfunction(space, start_date, end_date, optionalArgument4)

Should return:

[1] https://myapi.com/getData?hello&space={s:'earth'}&period={M:{start:'2018-10'end:'2018-11'}}&segment="ocean

I am litteraly stuck... Do you have any on how to manage this? Thanks for your help

Upvotes: 1

Views: 3338

Answers (2)

ebeneditos
ebeneditos

Reputation: 2612

You can do:

myfunction <- function(space, start_date, end_date, ..., optionalArgument4 = NULL){

  args <- c(...)

  filters <- paste(unlist(lapply(seq_along(args),
                           function(i) sprintf("SMALL_filter%s:{$sf%s:'%s'}",
                                                              i, i, args[i]))),
                   collapse = ",")

  api_request <- paste0("https://myapi.com/getData?hello",

                        #NEEDED
                        "&space={s:'", space,"'}",
                        "&period={M:{start:'",start_date,"',end:'",end_date,"'}}",

                        #OPTIONAL
                        ifelse(filters=="","",sprintf("&filter={%s}",filters)),

                        ifelse(!is.null(optionalArgument4),
                               paste0("&segment=",optionalArgument4),"")

  )

  return(api_request)    
}

You will have to name optionalArgument4 when calling the function:

space <- "earth"
start_date <- "2018-10"
end_date <- "2018-11"
optionalArgument1 <- "America"
optionalArgument2 <- "people"
optionalArgument3 <- "size"
optionalArgument4 <- "ocean"

myfunction(space, start_date, end_date, optionalArgument1, optionalArgument4 = optionalArgument4)
# [1] "https://myapi.com/getData?hello&space={s:'earth'}&period={M:{start:'2018-10',end:'2018-11'}}&filter={SMALL_filter1:{$sf1:'America'}}&segment=ocean"

Upvotes: 2

Leonel Esteban Bracco
Leonel Esteban Bracco

Reputation: 21

First of all, you have missed a coma after "&date_start=". Then, i guess you can check how many optional options the function receives, and then past them all with the filter string. For this, is necessary to have NULL as default value for the optional arguments.

argument1 <- "2018-11"
argument2 <- "2018-12"
optionalArgument1 <- "my_first_filter"
optionalArgument2 <- "my_second_filter"
optionalArgument3 <- "my_third_filter"

myfunction <- function (argument1, argument2, optionalArgument1 = NULL, optionalArgument2 = NULL, optionalArgument3 =NULL) {

  optional_options = c(optionalArgument1,optionalArgument2,optionalArgument3)
  optional_request = paste0("&filter=",optional_options,collapse = "")
  api_request <- paste0("myapiurl.com/getData?",
                        "&date_start=",argument1,
                        "&date_end=",argument2,optional_request)

  return(api_request)    
}
myfunction(argument1,argument2, optionalArgument1,optionalArgument2)

This code, and using only two optional arguments have this output:

> myfunction(argument1,argument2, optionalArgument1,optionalArgument2)
[1] "myapiurl.com/getData?&date_start=2018-11&date_end=2018-12&filter=my_first_filter&filter=my_second_filter"

I hope this helps.

UPDATE: after your new request i have made this code, but i think you should have been able to do it if you have wanted to use what i said before.

space <- "earth"
start_date <- "2018-10"
end_date <- "2018-11"
optionalArgument1 <- "America"
optionalArgument2 <- "people"
optionalArgument3 <- "size"
optionalArgument4 <- "ocean"

myfunction <- function(space, start_date, end_date, optionalArgument1=NULL, optionalArgument2=NULL, optionalArgument3=NULL, optionalArgument4=NULL){

  optional_options = c(optionalArgument1,optionalArgument2,optionalArgument3)
  optional_request=NULL
  if(length(optional_options>0)){
    optional_request = paste("&filter=",paste0("{SMALL_filter1:{$sf1:'",optional_options,"}",collapse = ""),collapse = "",sep = "")
  }
  if(!is.null(optionalArgument4)){
    optional_request = paste(optional_request,"&filter={",optionalArgument4,"}",sep="",collapse = "")
  }

  api_request <- paste0("https://myapi.com/getData?hello",

                        #NEEDED
                        "&space={s:'", space,"'}",
                        "&period={M:{start:'",start_date,"',end:'",end_date,"'}}",optional_request)


  return(api_request)    
}

and the output:

> myfunction(space, start_date, end_date, optionalArgument1, optionalArgument4=optionalArgument4)
[1] "https://myapi.com/getData?hello&space={s:'earth'}&period={M:{start:'2018-10',end:'2018-11'}}&filter={SMALL_filter1:{$sf1:'America}&filter={ocean}"
> myfunction(space, start_date, end_date, optionalArgument4=optionalArgument4)
[1] "https://myapi.com/getData?hello&space={s:'earth'}&period={M:{start:'2018-10',end:'2018-11'}}&filter={ocean}"

take note that you have to name the argument4, because it has to be treated separately and therefore cannot be used by argument order.

Upvotes: 1

Related Questions