多个组的多重反应的ANOVA,不是公式的一部分

时间:2014-04-24 21:46:54

标签: r anova

我正在努力弄清楚如何在多种环境中对一组响应进行ANOVA测试。样本类型。我有一个很大的数据框,我想通过这些分组因子分别运行这些ANOVA,但它们不应该包含在公式中。

也许我错过了一个明显的方法来做到这一点,但到目前为止,我只是将数据分组是很乏味的事情。

在SAS中,这类似于PROC语句中的BY语句。在SAS中很容易做到。

以下是一个例子:

data(iris)
data = iris

# suppose the iris data was in two environments..
data$location = unlist(rep(list("US", "USSR"), length(data$Sepal.Length)/2))
data$location = as.factor(data$location)
# and suppose that there was another subgrouping..
data$subgroup = unlist(list(rep(c(rep("A", 25), rep("B", 25)), 3)))
data$subgroup = as.factor(data$subgroup)
# and suppose I only want to look at the differences between two species
somedata = subset(data, Species == "setosa" | Species == "versicolor")
somedata = droplevels(somedata)
# suppose that I want to test if sepal length and sepal width are different..
# between species BY location AND BY subgroup
# and I'm only interested in the pvalues for these comparisons
# in my real data, I have more than just two responses I want to test..

# I could subset all the data.. which is what I've been doing..
# by location
dataUS = subset(somedata, location == "US")
dataUSSR = subset(somedata, location == "USSR")

# then by species
dataUS_A = subset(dataUS, subgroup=="A")
dataUS_B = subset(dataUS, subgroup=="B")

dataUSSR_A = subset(dataUSSR, subgroup=="A")
dataUSSR_B = subset(dataUSSR, subgroup=="B")

t.test(Sepal.Width ~ Species, data=dataUS_A)

有人能提供更快捷的方法来获取这些比较的p值吗? 可能有多种测试控制,如tukey?

我也尝试以长格式制作数据,并使用子集选项,但这几乎是乏味的。

我看过anova,aov和其他一些方法,但我已经陷入了困境。 我也试过制作我的数据格式并做这样的事情:

summary( aov(as.matrix(cbind(somedata[,c(1:2)])) ~ Species*location*subgroup, data=somedata) )

但我仍然无法弄清楚如何分组和子组

我还尝试将列连接到一个大的“组”列中,并将该新列用作我的分组,但这也不起作用:

somedata$group = do.call(paste, c(somedata[c("location","subgroup")], sep = "_"))

3 个答案:

答案 0 :(得分:3)

好的,首先,您的代码不必要地复杂化。查看下面的几个简化,希望使事情变得更简单。

然后,对于您的核心问题,您需要一种拆分应用组合策略。您需要通过相关的分组变量拆分数据,然后在每个数据子集中执行t.test。您可以结合splitlapply来实现这一目标。 (根据您的评论,要获得多个结果的结果,您需要嵌套的lapply函数)。

# the data, again
data <- iris
data$location <- factor(rep(c("US", "USSR"), length.out = length(data$Sepal.Length)))
data$subgroup <- factor(rep(c(rep("A", 25), rep("B", 25)), 3))
somedata <- data[data$Species %in% c("setosa","versicolor"),]

DVs <- c('Sepal.Width','Sepal.Length','Petal.Length')
out <- lapply(DVs, function(x){
    lapply(split(somedata, list(somedata$location, somedata$subgroup)),
    function(z) {
        t.test(update(~ Species,paste(x,'~.')), data=z)$p.value
     })
})

结果如下:

> do.call(cbind, setNames(out,DVs))
       Sepal.Width  Sepal.Length Petal.Length
US.A   9.183405e-05 9.371858e-06 5.852323e-14
USSR.A 0.0001211233 0.0001385488 2.97461e-12 
US.B   8.473525e-06 0.0001902751 4.123647e-11
USSR.B 0.001818272  5.308597e-06 7.593105e-11

答案 1 :(得分:2)

稍微简化你的代码:

data(iris)
df = iris
df$location = factor(rep(c("US", "USSR"), nrow(df)/2))
df$subgroup = factor(rep(c("A", "B"), each = 25, 3))
df = subset(df, Species != "virginica")

定义要用于

的功能
grouptest = function(dat){
    t.test(Sepal.Width ~ Species, data = dat)
}

按位置和子组运行:

by(df, df[,c("location", "subgroup")], FUN = grouptest)

答案 2 :(得分:0)

你看过R中的by函数了吗?如果这还不够,那么您可以考虑使用plyr包(用于拆分,操作,组合)。