如何简化R(正常性测试)中的代码:1行或2行代码中的样本大小不同?

问题描述 投票:0回答:2

我想在代码中进行一些正常的测试,并进行模拟(将测试重复1000次)。

sample <- c(10,30,50,100,500)
shapiro.test(rnorm(sample))

    Shapiro-Wilk normality test

data:  rnorm(sample)
W = 0.90644, p-value = 0.4465

如上所述,您只能看到一个输出。如何获得5个输出?我在这里缺少什么吗?

使用复制函数可为我提供每个样本大小1000个统计信息,而我仅对p值感兴趣,并将它们与显着性水平相关联。在各个正常性测试的编码中,我使用了以下代码(感谢用户StupidWolf,在我先前关于stackoverflow的问题中)

replicate_sw10 = replicate(1000,shapiro.test(rnorm(10)))
table(replicate_sw10["p.value",]<0.10)/1000
#which gave the following output
> FALSE  TRUE 
> 0.896 0.104
r normal-distribution
2个回答
1
投票

使用purrr

map(sample, function(x) shapiro.test(rnorm(x)))

给出

[[1]]

    Shapiro-Wilk normality test

data:  rnorm(x)
W = 0.92567, p-value = 0.4067


[[2]]

    Shapiro-Wilk normality test

data:  rnorm(x)
W = 0.95621, p-value = 0.247


[[3]]

    Shapiro-Wilk normality test

data:  rnorm(x)
W = 0.96144, p-value = 0.1021


[[4]]

    Shapiro-Wilk normality test

data:  rnorm(x)
W = 0.98654, p-value = 0.4077


[[5]]

    Shapiro-Wilk normality test

data:  rnorm(x)
W = 0.99597, p-value = 0.2324

编辑:因此,在您进行编辑后,您需要一个表。这不适用于您使用copy_sw10示例的方式,因为它是一个矩阵,而map(或对此不适用)会生成一个列表。因此,您再次想要使用Apply或Map在列表的所有部分上执行相同的转换。

replicate_swall  <- map(sample, function(x) shapiro.test(rnorm(x)))

replicate_pvalue_extract <- map(replicate_swall  , function(x) x["p.value",]) %>% unlist(., recursive = F)

table(replicate_pvalue_extract  < 0.10) / length(replicate_pvalue_extract )

这会给您:

FALSE  TRUE 
0.896 0.104 

另一个选项是使用magrittr软件包进行提取。您的代码将看起来像

replicate_pvalue_extract <- map(replicate_swall, magrittr::extract, "p.value") %>% unlist(., recursive = F)

table(replicate_pvalue_extract  < 0.10) / length(replicate_pvalue_extract )

在上面的代码中,我假设您希望将表划分为所有重复项,并且输入的内容无关紧要(对于输入,我的意思是10、30、50、100或500)。如果您确实关心输入内容,可以将它们分开,我将在下面提供代码。另请注意,我使用长度而不是您的硬编码/ 1000。这样,您的代码就更通用了,如果您更改复制编号,则除以表的数字也会自动更改。否则,您必须在多个位置进行更改(特别是如果其他人使用您的代码),这很容易导致错误。

replicate_pvalue_extract <- map(replicate_swall  , function(x) x["p.value",]) 

map(replicate_pvalue_extract  , function(x) table(x < 0.10) / length(x))

或者您可以将它们组合:

map(map(replicate_swall, function(x) x["p.value",]), function(x) table(x < 0.10) / length(x))

这就是为什么我给您magrittr选项的原因,因为我两次都不喜欢function(x)。使用magrittr,它看起来像:

map(map(replicate_swall, magrittr::extract, "p.value"), function(x) table(x < 0.10) / length(x))

这将导致:

[[1]]

FALSE  TRUE 
0.896 0.104 

[[2]]

FALSE  TRUE 
0.889 0.111 

[[3]]

FALSE  TRUE 
0.904 0.096 

[[4]]

FALSE  TRUE 
  0.9   0.1 

[[5]]

FALSE  TRUE 
0.891 0.109 

0
投票

您可以简单地使用$p.value。下面的代码将生成一个矩阵,其中包含1000行用于重复,而5列用于smpl大小。如果您想要列表作为结果,只需使用lapply而不是sapply

smpl <- c(10, 30, 50, 100, 500)

set.seed(42)  ## for sake of reproducibility

res <- sapply(smpl, function(x) replicate(1e3, shapiro.test(rnorm(x))$p.value))
head(res)
#            [,1]      [,2]       [,3]      [,4]      [,5]
# [1,] 0.43524553 0.5624891 0.02116901 0.8972087 0.8010757
# [2,] 0.67500688 0.1417968 0.03722656 0.7614192 0.7559309
# [3,] 0.52777713 0.6728819 0.67880178 0.1455375 0.7734797
# [4,] 0.55618980 0.1736095 0.69879316 0.4950400 0.5181642
# [5,] 0.93774782 0.9077292 0.58930787 0.2687687 0.8435223
# [6,] 0.01444456 0.1214157 0.07042380 0.4479121 0.7982574
© www.soinside.com 2019 - 2024. All rights reserved.