在R中检查数据是否服从正态分布

59

请问有人能帮我填写下面的R函数吗:

#data is a single vector of decimal values
normally.distributed <- function(data) {
if(data is normal)
return(TRUE)
else
return(NO)
}

2
你的问题并不是很明确。你是否在寻找一个函数来评估一个数字向量是否像是从正态分布中随机抽取的?如果是这样,那为什么不直接说呢? - Karl
8个回答

188

正态性检验并不是大多数人以为的那样。Shapiro检验、Anderson-Darling检验和其他检验都是针对正态分布假设进行的零假设检验。这些检验不能确定是否应该使用正态理论统计程序。实际上,它们对数据分析师几乎没有价值。在什么情况下我们有兴趣拒绝数据符合正态分布的零假设?我从未遇到过需要进行正态性检验的情况。当样本量很小时,即使与正态分布有很大的偏差也无法检测出来,而当你的样本量很大时,即使稍微偏离正态分布也会导致零假设被拒绝。

例如:

> set.seed(100)
> x <- rbinom(15,5,.6)
> shapiro.test(x)

    Shapiro-Wilk normality test

data:  x 
W = 0.8816, p-value = 0.0502

> x <- rlnorm(20,0,.4)
> shapiro.test(x)

    Shapiro-Wilk normality test

data:  x 
W = 0.9405, p-value = 0.2453

因此,在这两种情况下(二项式和对数正态变量),p值> 0.05,导致无法拒绝零假设(即数据是正态分布的)。这是否意味着我们得出结论数据是正常的?(提示:答案是否定的)。未能拒绝与接受不是同一件事。这是假设检验的基础知识。
但是对于更大的样本大小呢?让我们看一下分布非常接近正态分布的情况。
> library(nortest)
> x <- rt(500000,200)
> ad.test(x)

    Anderson-Darling normality test

data:  x 
A = 1.1003, p-value = 0.006975

> qqnorm(x)

输入图像描述 输入图像描述

这里我们使用自由度为200的t分布。QQ图显示该分布比你在现实世界中可能看到的任何分布更接近于正态分布,但是该检验以非常高的置信度拒绝了正态性。

显著性检验对正态性的拒绝是否意味着我们在这种情况下不应使用正态理论统计学?(另一个提示:答案是否定的 :))


10
非常好。跟进的大问题(我还没有找到令人满意的答案,希望有一个简单的答案可以给我的学生,但我怀疑是否有这样一个答案)是:如果使用回归的图形诊断,如何(除了拟合对一定类别的违规做出鲁棒性处理的模型/遵循流程,并显示其结果没有明显差异)决定是否担忧某种违规类型? - Ben Bolker
19
对于线性回归......1. 不要过于担心正态性。中心极限定理很快就会发挥作用,如果你的样本大小除了最小的样本外,直方图看起来合理,那么你就没问题了。2. 关注不平衡的方差(异方差性)。我担心到几乎默认使用HCCM测试。比例-位置图可以部分地判断是否存在异方差性,但并非总是如此。此外,在大多数情况下,没有先验理由假设等方差性。3. 异常值。Cook's距离大于1是合理的关注点。以上是我的想法(供参考)。 - Ian Fellows
3
我已经反复阅读了这篇文章数次。文章清晰吗?(提示:答案是否定的)。我想得到一个简单的答案来回答一个简单的问题,即数据是否符合正态分布。这篇文章提供了解决方案吗?(提示:答案是“否”)。 - stackoverflowuser2010
5
@stackoverflowuser2010,这里有两个明确的答案回复您简单的问题:(1) 无论您收集多少数据,都不能确定它是从完全正态分布生成的。(2) 您的数据不是从完全正态分布生成的(实际数据均非如此)。 - Ian Fellows
15
@stackoverflowuser2010,真可爱。我特别喜欢这张个人照片。不过在你拍摄之前,也许你应该试着搜索一下我的资料。 - Ian Fellows
显示剩余7条评论

25

我强烈推荐在TeachingDemos包中使用SnowsPenultimateNormalityTest。然而,与其说是测试本身,这个函数文档对你更有用。在使用该测试之前,请仔细阅读文档。


"SnowsPenultimateNormalityTest" 让我想起了这个 XKCD漫画 :) - adilapapaya

13

SnowsPenultimateNormalityTest肯定有其优点,但您可能还想看看qqnorm

X <- rlnorm(100)
qqnorm(X)
qqnorm(rnorm(100))

5
考虑使用函数shapiro.test,它可以执行Shapiro-Wilks正态性检验。我很满意它的表现。

4
通常情况下,这种方法适用于样本较小的情况(n < 50),但是也可以用于样本数量在2000左右的情况——在我看来,这个样本大小相对较小。 - derelict

3
library(DnE)
x<-rnorm(1000,0,1)
is.norm(x,10,0.05)

4
我不想过于负面,但(忽略所有关于为什么正态性检验可能是一个糟糕想法的更大背景答案),我担心这个软件包——它使用的测试没有文档记录。它与基础 R 中的测试以及 nortestnormtest 软件包中的测试有何区别(如Shapiro-Wilk、Anderson-Darling、Jarque-Bera等),这些测试在统计学文献中都非常仔细地描述了吗? - Ben Bolker
在花费了几秒钟的时间查看该软件包后,我认为可以说它相当粗糙。它将数据分成箱子并进行卡方检验;虽然这种方法是通用的,但几乎肯定比更知名的测试方法要弱。 - Ben Bolker

1
安德森-达林检验也是有用的。
library(nortest)
ad.test(data)

如果p值小于0.05,这是否意味着数据服从正态分布? - ah bon

1
除了qq图和Shapiro-Wilk检验之外,以下方法可能也很有用。
定性方法: - 与正态分布比较的直方图 - 与正态分布比较的累积分布函数图 - ggdensity图 - ggqqplot图
定量方法: - nortest包正态性检验链接 - normtest包正态性检验链接 可以使用以下代码在R中生成定性方法。
library("ggpubr")
library("car")

h <- hist(data, breaks = 10, density = 10, col = "darkgray") 
xfit <- seq(min(data), max(data), length = 40) 
yfit <- dnorm(xfit, mean = mean(data), sd = sd(data)) 
yfit <- yfit * diff(h$mids[1:2]) * length(data) 
lines(xfit, yfit, col = "black", lwd = 2)

plot(ecdf(data), main="CDF")
lines(ecdf(rnorm(10000)),col="red")

ggdensity(data)

ggqqplot(data)

警告 - 不要盲目应用测试。具备扎实的统计学知识将有助于您了解何时使用哪些测试以及假设检验中假设的重要性。


0

当你进行测试时,即使零假设为真,你也有可能拒绝它。

请看下面的 R 代码:

p=function(n){
  x=rnorm(n,0,1)
  s=shapiro.test(x)
  s$p.value
}

rep1=replicate(1000,p(5))
rep2=replicate(1000,p(100))
plot(density(rep1))
lines(density(rep2),col="blue")
abline(v=0.05,lty=3)

图表显示,无论样本大小是大还是小,在5%的情况下,您有机会在零假设为真时拒绝它(一种类型I错误)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接