How to make a custom function more robust and less error prone

Here are my details:

LoDFs <- list(first = mtcars[, c(1:3)], second = mtcars[, c(4:6)])
row.names(LoDFs[[1]]) <- NULL
row.names(LoDFs[[2]]) <- NULL

Here is my function:

RollapplyMultipleFuncsAndWins <- function(df.val, df.name, window.size, funs, ..., GroupByWindowSize = TRUE){
  library(zoo) # REQUIRED FOR rollapply
  by.rows <- 1
  combinations  <- expand.grid(window.size, funs)
  combinations  <- cbind(combinations, rep(names(funs), each = length(window.size)))
  colnames(combinations) <- c("window.size", "func.call", "func.name")
  combinations$window.size <- sprintf(paste0("%0", max(nchar(combinations$window.size)), "d"),
                                      combinations$window.size)

  LoMs <- apply(combinations, by.rows, function(x) {
                                                     rollapply(
                                                        df.val,
                                                        width = as.numeric(x[["window.size"]]),
                                                        by    = as.numeric(x[["window.size"]]),
                                                        FUN   = x[["func.call"]],
                                                        align = "left")})

  # COLUMN NAMING CONVENTION: column_name.function_name
  LoMs <- lapply(seq_along(LoMs), function(x) {
                                                colnames(LoMs[[x]]) <- paste(colnames(LoMs[[x]]),
                                                                             combinations$func.name[x],
                                                                             sep=".");
                                                LoMs[[x]] })

  # MULTIPLE FUNCTIONS WITH SAME WINDOW SIZE IN ONE DATASETS
  # LIST ELEMENTS NAMING CONVENTION: dataset_name.window_size
  if (GroupByWindowSize){
    df.win.grps <- lapply(unique(combinations$window.size), function(x) { grep(x, combinations$window.size) })
    LoMs        <- lapply(df.win.grps, function(x){ do.call(cbind, LoMs[x]) })

    names(LoMs) <- paste(rep(df.name, each=length(df.win.grps)),
                         unique(combinations$window.size),
                         sep=".")
  }
  # MULTIPLE FUNCTIONS WITH SAME WINDOW SIZE IN MULTIPLE DATASETS
  # LIST ELEMENTS NAMING CONVENTION: dataset_name.function_name.window_size
  else {
    names(LoMs) <- paste(rep(df.name, each=nrow(combinations)),
                         combinations$func.name,
                         combinations$window.size,
                         sep=".")
  }
  return(LoMs)
}

The purpose of this function is to apply several functions with several window sizes to move / move over one data set. It takes roller / displacement sizes and functions as input and creates all possible combinations of these values. For example, when you pass on c(2, 3, 10)how window.sizeand c(median = median, mean = mean)how funs, it will create the following combinations (which say that medianthey meanwill be called with a rolling / moving size window 2, 3, 10for the specified data set):

  window.size                                         func.call func.name
1          02 function (x, na.rm = FALSE) , UseMethod("median")    median
2          03 function (x, na.rm = FALSE) , UseMethod("median")    median
3          10 function (x, na.rm = FALSE) , UseMethod("median")    median
4          02             function (x, ...) , UseMethod("mean")      mean
5          03             function (x, ...) , UseMethod("mean")      mean
6          10             function (x, ...) , UseMethod("mean")      mean

, , , ( GroupByWindowSize - TRUE) , , ( GroupByWindowSize FALSE). , . , :

res_one_def     <- RollapplyMultipleFuncsAndWins(LoDFs[[1]], names(LoDFs)[1], c(2, 3), c(median = median, mean = mean))
res_one_non_def <- RollapplyMultipleFuncsAndWins(LoDFs[[1]], names(LoDFs)[1], c(2, 3), c(median = median, mean = mean), GroupByWindowSize=FALSE)

, , , :

res_one_def     <- RollapplyMultipleFuncsAndWins(LoDFs[[1]], names(LoDFs)[1], c(1), c(median = median, mean = mean))

, LoMs <- apply(combinations, by.rows, function(x) { ..... ( ) , , ( , , ):

  window.size                                         func.call func.name
1           1 function (x, na.rm = FALSE) , UseMethod("median")    median
2           1             function (x, ...) , UseMethod("mean")      mean

:

  • ?
  • , , combinations expand.grid(window.size, funs), , expand.grid(funs, window.size) ( ), if (GroupByWindowSize){ (, combinations , )?
  • - dataset_name.window_size , . dataset_name.function_name.window_size if-else? , names(LoMs) ... , , - ?
  • ? ? .

PS: "" "" R, , , .

PPS: , , , , codereview, .

+4

All Articles