简体   繁体   中英

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

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.

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"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM