为什么R对象不能在函数或“for”循环中打印?

我有一个名为ddd的Rmatrix。 当我input这个时,一切工作正常:

i <- 1 shapiro.test(ddd[,y]) ad.test(ddd[,y]) stem(ddd[,y]) print(y) 

呼叫夏皮罗·威尔克,安德森·达林,并干所有的工作,并提取相同的专栏。

如果我把这个代码放在一个“for”循环中,那么对Shapiro Wilk和Anderson Darling的呼叫停止工作,而干叶呼叫和打印呼叫继续工作。

 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 

为什么所有的通话都不一样?

在一个循环中,自动打印被closures,因为它在一个函数内部。 如果要查看输出,则需要在两种情况下都明确地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])) } 

如果你想打印更多的testing,那么只需在循环中添加它们作为额外的行:

 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])) } 

但是这不是很有吸引力,除非你喜欢阅读大量的输出。 相反,为什么不保存拟合的testing对象,然后可以打印它们并进行调查,甚至可以处理它们以将testing统计信息和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 

现在说我想提取Wp-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 

这要比输出到屏幕上,然后你必须倒过来更好?

不是一个新的答案,但除了上面的内容:“flush.console()”是强制打印发生在循环中而不是之后。 只有在循环中使用print()的原因是显示进度,例如读取多个文件。

 for (i in 1:10) { print(i) flush.console() for(j in 1:100000) k <- 0 } 

来自Gavin Simpson的神奇回答。 我把最后一点魔力变成了一个function。

 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))