¿Por qué los objetos R no se imprimen en una función o en un bucle “para”?

Tengo una matriz R llamada ddd. Cuando entro en esto, todo funciona bien:

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

Las llamadas a Shapiro Wilk, Anderson Darling, y detener todo el trabajo, y extraer la misma columna.

Si pongo este código en un bucle “for”, las llamadas a Shapiro Wilk y Anderson Darling dejan de funcionar, mientras que las llamadas de tallo y hoja y la llamada de impresión continúan funcionando.

 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 

Lo mismo sucede si bash escribir una función. SW y AD no funcionan. Las otras llamadas lo hacen.

 > D  D(9) The decimal point is at the | 9 | 000 9 | 10 | 00000 [1] 9 

¿Por qué no todas las llamadas se comportan de la misma manera?

En un bucle, la impresión automática se desactiva, ya que está dentro de una función. Necesita print algo explícitamente en ambos casos si desea ver el resultado. Las [1] 9 cosas que está obteniendo se deben a que está imprimiendo explícitamente los valores de y .

Aquí hay un ejemplo de cómo es posible que desee considerar hacer esto.

 > 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 

Entonces tenemos impresión automática. En el ciclo, tendríamos que hacer esto:

 for(y in 1:2) { print(shapiro.test(DF[,y])) } 

Si desea imprimir más pruebas, simplemente agréguelas como líneas adicionales en el ciclo:

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

Pero eso no es muy atractivo a menos que le guste leer a través de resmas de salida. En su lugar, ¿por qué no guardar los objetos de prueba ajustados y luego puede imprimirlos e investigarlos, tal vez incluso procesarlos para agregar las estadísticas de prueba y los valores p en una tabla? Puedes hacer eso usando un bucle:

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

Entonces podemos ver los modelos usando

 > obj[[1]] Shapiro-Wilk normality test data: DF[, y] W = 0.9891, p-value = 0.5895 

por ejemplo, o usando lapply , que se encarga de configurar el objeto que usamos para almacenar los resultados:

 > obj2 <- lapply(DF, shapiro.test) > obj2[[1]] Shapiro-Wilk normality test data: X[[1L]] W = 0.9891, p-value = 0.5895 

Digamos ahora que quería extraer los datos W y p-value , podemos procesar el objeto que almacena todos los resultados para extraer los bits que queremos, por ejemplo:

 > 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 

O para aquellos con una inclinación por las estrellas significativas:

 > 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 

Esto tiene que ser mejor que disparar la salida a la pantalla que luego tiene que pasar?

No es una respuesta nueva, pero además de lo anterior: “flush.console ()” es necesario para forzar la impresión DURANTE el ciclo en lugar de hacerlo después. La única razón por la que uso print () durante un ciclo es para mostrar el progreso, por ejemplo, de leer muchos archivos.

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

Fantástica respuesta de Gavin Simpson. Tomé la última parte de la magia y la convertí en una función.

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

Luego puede llamarlo con su dataframe sw.df (df)

Y si quieres probar una transformación: sw.df (log (df))

    Intereting Posts