为啥 R 对象不在函数或“for”循环中打印?
Posted
技术标签:
【中文标题】为啥 R 对象不在函数或“for”循环中打印?【英文标题】:Why do R objects not print in a function or a "for" loop?为什么 R 对象不在函数或“for”循环中打印? 【发布时间】:2011-06-10 14:39:43 【问题描述】:我有一个名为 ddd 的 R 矩阵。当我输入这个时,一切正常:
i <- 1
shapiro.test(ddd[,y])
ad.test(ddd[,y])
stem(ddd[,y])
print(y)
对 Shapiro Wilk、Anderson Darling 和 stem 的调用都有效,并提取同一列。
如果我将此代码放在“for”循环中,对 Shapiro Wilk 和 Anderson Darling 的调用将停止工作,而茎叶调用和 print 调用将继续工作。
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
如果我尝试编写一个函数,也会发生同样的事情。 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
为什么所有调用的行为方式不同?
【问题讨论】:
i
是什么意思 - 你是说第一行中的 y <- 1
吗?
【参考方案1】:
在一个循环中,自动打印被关闭,因为它在一个函数内部。如果你想看到输出,你需要在这两种情况下明确地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
所以我们有自动打印。在循环中,我们必须这样做:
for(y in 1:2)
print(shapiro.test(DF[,y]))
如果您想打印更多测试,只需将它们添加为循环中的额外行:
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]))
但这并不是很吸引人,除非你喜欢阅读大量的输出。相反,为什么不保存拟合的测试对象,然后您可以打印它们并研究它们,甚至可以处理它们以将测试统计数据和 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])
然后我们可以查看模型使用
> obj[[1]]
Shapiro-Wilk normality test
data: DF[, y]
W = 0.9891, p-value = 0.5895
例如,或者使用lapply
,它负责设置我们用来为我们存储结果的对象:
> obj2 <- lapply(DF, shapiro.test)
> obj2[[1]]
Shapiro-Wilk normality test
data: X[[1L]]
W = 0.9891, p-value = 0.5895
现在假设我想提取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
或者对于那些喜欢重要明星的人:
> 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
这一定比向屏幕输出输出要好,然后你必须倾泻而出?
【讨论】:
非常感谢,加文。我不知道“打印”在循环和函数中被关闭。医生没这么说。我也不熟悉“y in seq_along(obj)”。不知道你能做到!你的回答很有帮助。 我不知道'printCoefmat'。太好了!!【参考方案2】:不是一个新的答案,但除上述之外:“flush.console()”对于强制在循环期间而不是之后进行打印是必要的。我在循环中使用 print() 的唯一原因是显示进度,例如,读取许多文件。
for (i in 1:10)
print(i)
flush.console()
for(j in 1:100000)
k <- 0
【讨论】:
对回答标题中的问题投赞成票。这应该被编辑,因此这个问题的标题与问题本身不匹配。【参考方案3】:来自 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)
然后你可以用你的数据框来调用它 sw.df ( df )
如果您想尝试转换: sw.df ( log(df) )
【讨论】:
以上是关于为啥 R 对象不在函数或“for”循环中打印?的主要内容,如果未能解决你的问题,请参考以下文章
如何循环 JSON 数据以获取所有对象的打印百分比值,使用 for each 或 other [重复]