在数据框中的多个列上使用shapiro.test

Seb*_*ros 6 statistics r function dataframe

这似乎是一个非常简单的问题,但我找不到答案.

我有一个数据帧(让调用它df),包含n = 100列(C1,C2..., C100)和50行(R1,R2..., R50).我测试了数据框中的所有列,以确保它们是数字的.我想知道每列中的数据是否具有使用该shapiro.test()函数的正态分布.

我能够使用代码逐列进行:

> shapiro.test(df$Cn)
Run Code Online (Sandbox Code Playgroud)

要么

> shapiro.test(df[,c(Cn)])
Run Code Online (Sandbox Code Playgroud)

但是当我尝试在几个列上同时执行它时它不起作用:

> shapiro.test(df[,c(C1:C100)])
Run Code Online (Sandbox Code Playgroud)

返回错误:

Error in `[.data.frame`(x, complete.cases(x)) : undefined columns selected
Run Code Online (Sandbox Code Playgroud)

如果有人能够建议同时进行所有测试的方法,并最终将结果存储在新的数据帧/矩阵/列表/向量中,我将不胜感激.

谢谢 !

勒布

Rei*_*son 11

并不是说我认为这是一种合理的数据分析方法,但是将函数应用于数据框的列的基本问题是一个通用任务,可以使用sapply()或者lapply()(或者甚至apply()是数据帧)轻松实现.前面提到的两个函数之一是最好的.

这是一个使用一些虚拟数据的例子:

set.seed(42)
df <- data.frame(Gaussian = rnorm(50), Poisson = rpois(50, 2), 
                 Uniform = runif(50))
Run Code Online (Sandbox Code Playgroud)

现在应用该shapiro.test()功能.我们在列表中捕获输出(给定此函数返回的对象),因此我们将使用lapply().

lshap <- lapply(df, shapiro.test)
lshap[[1]] ## look at the first column results

R> lshap[[1]]

    Shapiro-Wilk normality test

data:  X[[1L]]
W = 0.9802, p-value = 0.5611
Run Code Online (Sandbox Code Playgroud)

您需要从这些对象中提取所需的内容,这些对象都具有以下结构:

R> str(lshap[[1]])
List of 4
 $ statistic: Named num 0.98
  ..- attr(*, "names")= chr "W"
 $ p.value  : num 0.561
 $ method   : chr "Shapiro-Wilk normality test"
 $ data.name: chr "X[[1L]]"
 - attr(*, "class")= chr "htest"
Run Code Online (Sandbox Code Playgroud)

如果你想要这个对象的statistic和p.value组件用于所有元素lshap,我们将使用sapply()这个时间,为我们很好地安排结果:

lres <- sapply(lshap, `[`, c("statistic","p.value"))

R> lres
          Gaussian Poisson Uniform 
statistic 0.9802   0.9371  0.918   
p.value   0.5611   0.01034 0.001998
Run Code Online (Sandbox Code Playgroud)

鉴于你有500个,我转换lres:

R> t(lres)
         statistic p.value 
Gaussian 0.9802    0.5611  
Poisson  0.9371    0.01034 
Uniform  0.918     0.001998
Run Code Online (Sandbox Code Playgroud)

如果你计划用这个练习的p值做任何事情,我建议你开始考虑如何纠正多次比较,然后用30-cal射击自己的脚.

  • 无论你做什么,你都需要纠正做所有这些测试。如果您进行了 100 次测试并使用了通常的 0.05 (alpha=0.95) 显着性水平,那么您接受了当 HO 正确时,您将在 100 次中平均拒绝 NULL (H0) 5 次(即您会发现一个重要的结果)不存在的地方)。在进行多个测试时,您需要考虑到这一点,因此请查看 Bonferroni &amp; Holm 调整、FDR(错误发现率)等。这可以通过 `p.adjust()` 来完成。 (2认同)

ton*_*nov 5

要对数据框的行或列应用一些函数,可以使用applyfamily:

df <- data.frame(a=rnorm(100), b=rnorm(100))    
df.shapiro <- apply(df, 2, shapiro.test)
df.shapiro
$a

    Shapiro-Wilk normality test

data:  newX[, i]
W = 0.9895, p-value = 0.6276


$b

    Shapiro-Wilk normality test

data:  newX[, i]
W = 0.9854, p-value = 0.3371
Run Code Online (Sandbox Code Playgroud)

请注意,列名被保留,并且df.shapiro是一个命名列表。

现在,如果你想要一个 p 值向量,你所要做的就是从适当的列表中提取它们:

unlist(lapply(df.shapiro, function(x) x$p.value))
        a         b 
0.6275521 0.3370931 
Run Code Online (Sandbox Code Playgroud)