如何为函数中的公式指定主观列
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))
我想编写一个函数,允许我指定数据、分组变量(Region
、State
或 Loc
)和变量的行名称 ( 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))
考虑在此处创建 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))
我想编写一个函数,允许我指定数据、分组变量(Region
、State
或 Loc
)和变量的行名称 ( 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))