Sal*_*gio 53 printing for-loop r r-faq
我有一个名为ddd的R矩阵.当我输入这个,一切正常:
i <- 1
shapiro.test(ddd[,y])
ad.test(ddd[,y])
stem(ddd[,y])
print(y)
Run Code Online (Sandbox Code Playgroud)
对Shapiro Wilk,Anderson Darling和stem的调用全部工作,并提取相同的专栏.
如果我把这段代码放在"for"循环中,那么对Shapiro Wilk和Anderson Darling的调用就会停止工作,而stem&leaf调用和打印调用将继续工作.
for (y in 7:10) {
shapiro.test(ddd[,y])
ad.test(ddd[,y])
stem(ddd[,y])
print(y)
}
The decimal point is 1 digit(s) to the right of the |
0 | 0
0 | 899999
1 | 0
[1] 7
Run Code Online (Sandbox Code Playgroud)
如果我尝试编写一个函数,会发生同样的事情.SW&AD不起作用.其他的电话呢.
> D <- function (y) {
+ shapiro.test(ddd[,y])
+ ad.test(ddd[,y])
+ stem(ddd[,y])
+ print(y) }
> D(9)
The decimal point is at the |
9 | 000
9 |
10 | 00000
[1] 9
Run Code Online (Sandbox Code Playgroud)
为什么不是所有的调用都以相同的方式运行?
Rei*_*son 56
在循环中,自动打印被关闭,因为它在函数内部.print如果要查看输出,则需要在两种情况下都明确表示某些内容.[1] 9你得到的东西是因为你明确地印刷了它的价值y.
以下是您可能想要考虑如何执行此操作的示例.
> DF <- data.frame(A = rnorm(100), B = rlnorm(100))
> y <- 1
> shapiro.test(DF[,y])
Shapiro-Wilk normality test
data: DF[, y]
W = 0.9891, p-value = 0.5895
Run Code Online (Sandbox Code Playgroud)
所以我们有自动打印.在循环中我们必须这样做:
for(y in 1:2) {
print(shapiro.test(DF[,y]))
}
Run Code Online (Sandbox Code Playgroud)
如果你想打印更多的测试,那么只需将它们作为额外的行添加到循环中:
for(y in 1:2) {
writeLines(paste("Shapiro Wilks Test for column", y))
print(shapiro.test(DF[,y]))
writeLines(paste("Anderson Darling Test for column", y))
print(ad.test(DF[,y]))
}
Run Code Online (Sandbox Code Playgroud)
但是,除非你喜欢阅读大量的输出,否则这不是很吸引人.相反,为什么不保存拟合的测试对象然后你可以打印它们并调查它们,甚至可以处理它们以将测试统计和p值聚合到表中?你可以使用循环来做到这一点:
## object of save fitted objects in
obj <- vector(mode = "list", length = 2)
## loop
for(y in seq_along(obj)) {
obj[[y]] <- shapiro.test(DF[,y])
}
Run Code Online (Sandbox Code Playgroud)
然后我们可以看一下使用的模型
> obj[[1]]
Shapiro-Wilk normality test
data: DF[, y]
W = 0.9891, p-value = 0.5895
Run Code Online (Sandbox Code Playgroud)
例如,或者使用lapply,它负责设置我们用来存储结果的对象:
> obj2 <- lapply(DF, shapiro.test)
> obj2[[1]]
Shapiro-Wilk normality test
data: X[[1L]]
W = 0.9891, p-value = 0.5895
Run Code Online (Sandbox Code Playgroud)
现在说我想提取W和p-value数据,我们可以处理存储所有结果的对象来提取我们想要的位,例如:
> tab <- t(sapply(obj2, function(x) c(x$statistic, x$p.value)))
> colnames(tab) <- c("W", "p.value")
> tab
W p.value
A 0.9890621 5.894563e-01
B 0.4589731 1.754559e-17
Run Code Online (Sandbox Code Playgroud)
或者对那些喜欢重要明星的人:
> tab2 <- lapply(obj2, function(x) c(W = unname(x$statistic),
+ `p.value` = x$p.value))
> tab2 <- data.frame(do.call(rbind, tab2))
> printCoefmat(tab2, has.Pvalue = TRUE)
W p.value
A 0.9891 0.5895
B 0.4590 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Run Code Online (Sandbox Code Playgroud)
这必须比向屏幕发射输出更好,然后你必须倾注?
J. *_*in. 39
这不是一个新的答案,但除了上述之外:"flush.console()"是强制打印在循环期间而不是之后发生的必要条件.我在循环期间使用print()的唯一原因是显示进度,例如,读取许多文件.
for (i in 1:10) {
print(i)
flush.console()
for(j in 1:100000)
k <- 0
}
Run Code Online (Sandbox Code Playgroud)
小智 5
Gavin Simpson的精彩回答.我拿出最后一点魔法并把它变成了一个函数.
sw.df <- function ( data ) {
obj <- lapply(data, shapiro.test)
tab <- lapply(obj, function(x) c(W = unname(x$statistic), `p.value` = x$p.value))
tab <- data.frame(do.call(rbind, tab))
printCoefmat(tab, has.Pvalue = TRUE)
}
Run Code Online (Sandbox Code Playgroud)
然后你可以用数据框sw.df(df)调用它
如果你想尝试转换:sw.df(log(df))