es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Argumento predeterminado dependiendo de la función coincidente en R.

Actualmente tengo dos envolturas muy similares alrededor de table y xtabs:

mytable <- function(..., useNA = "ifany") {
  tab <- table(..., useNA = useNA)
  # manipulaciones adicionales
  tab
}

mytable(warpbreaks[-1])

myxtabs <- function(..., na.action = NULL, addNA = TRUE) {
  tab <- xtabs(..., na.action = na.action, addNA = addNA)
  # mismas manipulaciones que en mytable
  tab
}

myxtabs(breaks ~ ., warpbreaks)

Como gran parte del código se repite, deseo combinar ambas envolturas en una sola. Una solución simple es:

newfun <- function(..., fun) {
  fun <- match.fun(fun)
  tab <- fun(...)
  # mismas manipulaciones que en mytable
  tab
}

newfun(warpbreaks[-1], fun = table)
newfun(breaks ~ ., warpbreaks, fun = xtabs)

Sin embargo, ¿puedo especificar argumentos predeterminados dependiendo de la función que se empareja? es decir:

  • si fun = table, establecer useNA = "ifany";
  • o si fun = xtabs, establecer na.action = NULL y addNA = TRUE.

Además, ¿cuál es la forma “recomendada” de restringir fun solo a table y xtabs? Supongo que hay muchas maneras de lograr esto (stopifnot, if/else, switch, match.arg), pero estoy buscando una buena práctica aquí.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para especificar argumentos predeterminados dependiendo de qué función se llame, puedes utilizar la función ifelse dentro del envoltorio newfun. Aquí hay una versión actualizada del código con esta modificación:

    newfun <- function(..., fun) {
      fun <- match.fun(fun)
      tab <- ifelse(fun == table, 
                    table(..., useNA = "ifany"), 
                    xtabs(..., na.action = NULL, addNA = TRUE))
      # manipulaciones adicionales
      tab
    }
    
    newfun(warpbreaks[-1], fun = table)
    newfun(breaks ~ ., warpbreaks, fun = xtabs)
    

    Para restringir el argumento fun solo a table y xtabs, puedes utilizar la función match.arg con el argumento choices especificado como un vector de caracteres de nombres de funciones permitidas. Aquí hay una versión actualizada del envoltorio newfun con esta modificación:

    newfun <- function(..., fun = "table") {
      fun <- match.arg(fun, choices = c("table", "xtabs"))
      tab <- ifelse(fun == "table", 
                    table(..., useNA = "ifany"), 
                    xtabs(..., na.action = NULL, addNA = TRUE))
      # manipulaciones adicionales
      tab
    }
    
    newfun(warpbreaks[-1], fun = "table")
    newfun(breaks ~ ., warpbreaks, fun = "xtabs")
    

    Este enfoque asegura que fun se restringa solo a los nombres de función permitidos y también te permite especificar un valor predeterminado para fun.

Comments are closed.