¿Podemos crear una matriz bidimensional para combinar combinaciones de dos argumentos de función?
Por ejemplo, si escribo una función con 1 argumento (además del argumento de entrada de datos):
choose_procedure <- function(x, what_to_do) { switch(what_to_do, "mean" = {...}, # mean(x) or mean(x, na.rm = TRUE) or weighted.mean(x) "median" = {...}, # median(x) "square" = {...}, # x * x or x ^ 2 "unique" = {...}, # unique(x) "log" = {...} # log(x) or log10(x) ) } Agregué comentarios en línea para implicar que podría haber más de una opción por entrada what_to_do .
Cuando what_to_do = "mean" , ¿debería ser mean(x, na.rm = TRUE) o mean(x, na.rm = FALSE) ? Del mismo modo, cuando what_to_do = "log" , ¿debería ser log(x) o log10(x) ? Etc.
Para manejar esto, pensé en introducir otro argumento para choose_procedure() , llamado "scenario" . Entonces, si la llamada a choose_procedure() es:
choose_procedure(x = mtcars$mpg, what_to_do = "log", scenario = "A") Entonces ejecutaría log(mtcars$mpg) .
Pero si la llamada es
choose_procedure(x = mtcars$mpg, what_to_do = "log", scenario = "B") entonces ejecutaría log10(mtcars$mpg) .
Un ejemplo con solo "log" y "scenario" describe una matriz de 2x2:
"what_to_do" tiene 2 opciones: log() o log10()"scenario" tiene dos opciones: "A" o "B" Claramente, esto podría manejarse con 4 declaraciones if (una para cada combinación), pero será muy difícil de programar si tenemos más combinaciones (como en el ejemplo de choose_procedure() con el que abrí).
Así que tengo dos preguntas:
"what_do_to" , "scenario" , "sub_scenario" . Etc.choose_procedure <- function(x, FUN, ...){ if(...length()) FUN(x, ...) else FUN(x) } x <- c(1,3,5,NA, 10) choose_procedure(x, mean) [1] NA choose_procedure(x, mean, na.rm = TRUE) [1] 4.75 choose_procedure(x, log) [1] 0.000000 1.098612 1.609438 NA 2.302585 choose_procedure(x, log10) [1] 0.0000000 0.4771213 0.6989700 NA 1.0000000Esta es una de esas cosas en las que hay muchas maneras de abordar el problema, y es muy probable que la mejor dependa del contexto en el que realmente desea usarla. Sin embargo, en la situación que describió, así es como lo abordaría. eso:
choose_procedure <- function(x, ...) { # Define a table of options choices <- tibble::tribble( ~what_to_do, ~scenario, ~result, "mean", "A", mean, "mean", "B", ~mean(., na.rm = TRUE), "mean", "C", weighted.mean, "median", "A", median, "square", "A", ~. * ., "square", "B", ~. ^ 2, "unique", "A", unique, "log", "A", log, "log", "B", log10 ) # Filter the table down to the desired option choice <- dplyr::filter(choices, ...) # Stop if no options available if (nrow(choice) == 0) { stop("No such option available") } # Warn if multiple options available, and use first if (nrow(choice) > 1) { choice <- head(choices, 1) warning("More than one option available, using first scenario") } # Transform any purrr-style lambda functions to normal functions fun <- rlang::as_function(choice$result[[1]]) # Perform the calculation fun(x) } choose_procedure(x = mtcars$mpg, what_to_do == "log", scenario == "B") #> [1] 1.322219 1.322219 1.357935 1.330414 1.271842 1.257679 1.155336 1.387390 #> [9] 1.357935 1.283301 1.250420 1.214844 1.238046 1.181844 1.017033 1.017033 #> [17] 1.167317 1.510545 1.482874 1.530200 1.332438 1.190332 1.181844 1.123852 #> [25] 1.283301 1.436163 1.414973 1.482874 1.198657 1.294466 1.176091 1.330414Creado el 2021-10-25 por el paquete reprex (v2.0.0)