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

时间:2014-01-20 16:57:27

标签: r function statistics dataframe

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

我有一个数据框(我们称之为df),包含n = 100列(C1C2,...,C100)和50行( R1R2,...,R50)。我测试了数据框中的所有列,以确保它们是数字的。我想知道每列中的数据是否使用shapiro.test()函数进行正态分布。

我可以使用代码逐列填写:

> shapiro.test(df$Cn)

> shapiro.test(df[,c(Cn)])

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

> shapiro.test(df[,c(C1:C100)])

返回错误:

Error in `[.data.frame`(x, complete.cases(x)) : undefined columns selected

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

谢谢!

的Seb

3 个答案:

答案 0 :(得分:8)

并不是说我认为这是一种合理的数据分析方法,但将函数应用于数据框列的根本问题是使用sapply()或{{}}之一轻松实现的一般性任务{1}}(甚至lapply(),但对于数据框,前面提到的两个函数中的一个最好。)

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

apply()

现在应用set.seed(42) df <- data.frame(Gaussian = rnorm(50), Poisson = rpois(50, 2), Uniform = runif(50)) 功能。我们在列表中捕获输出(给定此函数返回的对象),因此我们将使用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

如果您希望此对象的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" statistic组件适用于p.value的所有元素,我们这次将使用lshap,以便为我们很好地安排结果:

sapply()

鉴于你有500个,我会转换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

lres

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

答案 1 :(得分:2)

要在数据框的行或列上应用某些功能,请使用apply系列:

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

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

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

unlist(lapply(df.shapiro, function(x) x$p.value))
        a         b 
0.6275521 0.3370931 

答案 2 :(得分:0)

do.callrbindlapply一起使用,以获得更简单紧凑的解决方案:

df <- data.frame(a = rnorm(100), b = rnorm(100), c = rnorm(100))
do.call(rbind, lapply(df, function(x) shapiro.test(x)[c("statistic", "p.value")]))
#>   statistic p.value    
#> a 0.986224  0.3875904  
#> b 0.9894938 0.6238027
#> c 0.9652532 0.009694794