rfunctionfunctional-programmingmanova

How to specify subjective columns for a formula within a function


Consider dat1 created here:

dat1 <- data.frame(Region = rep(c("r1","r2"), each = 100),
                   State = rep(c("NY","MA","FL","GA"), each = 10),
                   Loc = rep(c("a","b","c","d","e","f","g","h"),each = 5),
                   ID = rep(c(1:10), each=2),
                   var1 = rnorm(200),
                   var2 = rnorm(200),
                   var3 = rnorm(200),
                   var4 = rnorm(200),
                   var5 = rnorm(200))

I want to write a function that will allow me to specify the data, grouping variable (Region,State, or Loc), and row names of the variables (var1:var5) with which I want it to conduct a manova and return the results in tidy format. Running the function would look something like this: manova.test(dat = dat1, groupvar = "Region", cols = 5:9)

The function would look something like this (which doesn't work):

manova.test <- function(dat, groupvar, cols){
   var.mat <- as.matrix(dat[, cols])
   group.man <- manova(cbind(var.mat) ~ groupvar, data = dat)
   summary(group.man)
 }

How do you do this? I am especially confused about how to specify the formula in this format!


Solution

  • You can use get to return the named object within the function. The drawback is that the variable will be labelled get(groupvar) in the summary, so I renamed it within your function:

    set.seed(1)
    dat1 <- data.frame(Region = rep(c("r1","r2"), each = 100),
                       State = rep(c("NY","MA","FL","GA"), each = 10),
                       Loc = rep(c("a","b","c","d","e","f","g","h"),each = 5),
                       ID = rep(c(1:10), each=2),
                       var1 = rnorm(200),
                       var2 = rnorm(200),
                       var3 = rnorm(200),
                       var4 = rnorm(200),
                       var5 = rnorm(200))
    
    manova.test <- function(dat, groupvar, cols){
        var.mat <- as.matrix(dat[, cols])
        group.man <- manova(cbind(var.mat) ~ get(groupvar), data = dat)
        s <- summary(group.man)
        dimnames(s$stats)[[1]][1] <- groupvar
        s
    }
    
    manova.test(dat = dat1, groupvar = "Region", cols = 5:9)
    #>            Df   Pillai approx F num Df den Df Pr(>F)
    #> Region      1 0.015933   0.6282      5    194 0.6784
    #> Residuals 198
    

    Created on 2020-05-27 by the reprex package (v0.3.0)