如何简化 R 中的代码(正态性检验):1 行或 2 行代码中的不同样本量?
How to simplify code in R (normality test): different sample sizes in 1 line or 2 lines of code?
我想在我的编码中进行更清晰的正态性测试并进行模拟(重复测试 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,在我之前在 Whosebug 上发布的问题中)
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
使用 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
编辑:所以在您编辑之后,您正在请求一些 table。这与您使用 replicate_sw10 示例的方式不同,因为它是一个矩阵,而 map (或 lapply 就此而言)会生成一个列表。因此,您再次想要使用 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 )
在上面的代码中,我假设您想将 table 除以所有重复项,并且输入是什么并不重要(输入是指 10、30、50、100 或 500) .如果您确实关心输入,可以将它们分开,我将在下面给出代码。另请注意,我使用的是长度而不是硬编码的 /1000。通过这种方式,您的代码更加通用,如果您更改重复编号,您除以 table 的编号也会自动更改。否则,您必须在多个位置进行更改(尤其是当其他人使用您的代码时),这很容易导致错误。
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
您可以简单地使用$p.value
。下面的代码生成一个矩阵,其中 1,000 行用于重复,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
我想在我的编码中进行更清晰的正态性测试并进行模拟(重复测试 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,在我之前在 Whosebug 上发布的问题中)
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
使用 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
编辑:所以在您编辑之后,您正在请求一些 table。这与您使用 replicate_sw10 示例的方式不同,因为它是一个矩阵,而 map (或 lapply 就此而言)会生成一个列表。因此,您再次想要使用 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 )
在上面的代码中,我假设您想将 table 除以所有重复项,并且输入是什么并不重要(输入是指 10、30、50、100 或 500) .如果您确实关心输入,可以将它们分开,我将在下面给出代码。另请注意,我使用的是长度而不是硬编码的 /1000。通过这种方式,您的代码更加通用,如果您更改重复编号,您除以 table 的编号也会自动更改。否则,您必须在多个位置进行更改(尤其是当其他人使用您的代码时),这很容易导致错误。
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
您可以简单地使用$p.value
。下面的代码生成一个矩阵,其中 1,000 行用于重复,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