如何为函数中的公式指定主观列

How to specify subjective columns for a formula within a function

考虑在此处创建 dat1

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))

我想编写一个函数,允许我指定数据、分组变量(RegionStateLoc)和变量的行名称 ( var1:var5) 我希望它用它来进行 manova 和 return 结果以整洁的格式。 运行 该函数看起来像这样:manova.test(dat = dat1, groupvar = "Region", cols = 5:9)

该函数看起来像这样(不起作用):

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

你是怎么做到的?我特别困惑如何指定这种格式的公式!

您可以使用get 来return 函数内的命名对象。缺点是变量会在摘要中被标记为get(groupvar),所以我在你的函数中重命名了它:

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

reprex package (v0.3.0)

于 2020-05-27 创建

如果您只是担心公式,那您就快到了。这应该有效

manova.test <- function(df, groupvar) {
  manova(cbind(var1, var2) ~ df[[groupvar]], data = df)
}

manova.test(dat1, "Region")

这是一种基于 win-vector 的方法。com/blog/2018/09/r-tip-how-to-pass-a-formula-to-lm/,这个解决方案的妙处在于您可以轻松地为多列扩展 groupvar

manova.test <- function(dat, groupvar, cols){
  paster <- function(x){
    paste(x,collapse = " + ")
  }

  groupvar <- dat %>% select({{groupvar}}) %>% names()

  var.mat <- as.matrix(dat %>% select({{cols}}))

  f <- paste("cbind(var.mat)", paster(groupvar), sep = " ~ " ) %>% as.formula()

  model <- eval(bquote(   manova(.(f), data = dat)))
  summary(model)
}

manova.test(dat1,c(Region,Loc),cols = c(var1:var5))