Brown Forsyth在R

时间:2016-07-20 19:40:20

标签: r

我想在两列中逐行执行brown forsyth testF-test for non-normally distributed data)。

我想要实现的一个例子如下:我希望很清楚。

D1 <- rnorm(n=50, mean = 10, sd = 5)
D2 <- rnorm(n=50, mean = 15, sd = 6)
D3 <- rnorm(n=50, mean = 20, sd = 5)
D4 <-rnorm(n=50, mean = 15, sd = 7)
Data1 <- data.frame(D1,D2,D3, D4)
medData1<- apply(Data1, 1, median)


A1 <- rnorm(n=50, mean = 15, sd = 6)
A2 <- rnorm(n=50, mean = 10, sd = 5)
A3 <- rnorm(n=50, mean = 10, sd = 7)
A4 <-rnorm(n=50, mean = 20, sd = 5)
Data2 <- data.frame(A1,A2,A3, A4)
medData2<- apply(Data2, 1, median)

meds<-data.frame(medData1,medData2)
> head(meds)
   medData1  medData2
1 15.194196 13.962238
2 15.443147  9.421257
3 16.436454 16.177326
4 10.042506 15.877342
5 14.793970 16.741701
6  9.709235 14.887777

使用medData1和medData2的中位数我想看看方差是否相等的假设是否为真,使用棕色连翘测试。我需要按行完成,因为每行都是数据集中的一个单独的点。

我假设循环可能是最好的从一行到下一行使测试循环但我尝试了不同的方法并失败了(因此我现在发布的原因:))

在我的实际数据中 - 每个数据集的中位数是从20个值计算的,我有572009个观察值(行)。

请告诉你最好的方法

提前致谢

1 个答案:

答案 0 :(得分:0)

根据Wikipedia,Brown-Forsythe检验是通过对每组中位数的绝对偏差进行单向ANOVA来完成的。但是,您仍然需要所有数据;如果你计算中位数并扔掉原始数据,你就会被卡住。

设置数据:

mkdata <- function(meanvec,sdvec,nmvec,n=50) {
    m <- mapply(rnorm,meanvec,sdvec,MoreArgs=list(n=n))
    d <- as.data.frame(m)
    names(d) <- nmvec
    return(d)
}
set.seed(101)
Data1 <- mkdata(c(10,15,20,15),c(5,6,5,7),paste0("D",1:4))
Data2 <- mkdata(c(15,10,10,20),c(6,5,7,5),paste0("A",1:4))

这不一定是最有效的方法,但它应该有效。基本上,我们设置一个由每个组的绝对偏差和分组因子组成的小数据集,拟合线性模型,并从摘要中提取p值。

testfun <- function(x,y) {
    x <- unlist(x); y <- unlist(y) ## nec if taking data from rows of a data frame
    d <- data.frame(g=factor(rep(1:2,c(length(x),length(y)))),
                    y=c(abs(x-median(x)),y=abs(y-median(y))))
    mod <- lm(y~g,data=d)
    pval <- coef(summary(mod))["g2","Pr(>|t|)"]
    return(pval)
}

res <- rep(NA,nrow(Data1))
for (i in 1:nrow(Data1)) res[i] <- testfun(Data1[i,],Data2[i,])

如果您需要加快速度,最简单的方法是将其并行化到多个核心(请参阅?parallel::mclapply)。通过将数据存储在矩阵而不是数据帧中,您可以节省一些时间......

PS我们可以将testfun(几乎)替换为car::leveneTest(几乎完全相同......)