2011-01-17 8 views
46

Tengo una matriz R llamada ddd. Cuando entro en esto, todo funciona bien:¿Por qué los objetos R no se imprimen en una función o en un bucle "for"?

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

Las llamadas a Shapiro Wilk, Anderson Darling y el vástago todo el trabajo y el extracto de 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 la llamada de la raíz & 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 ocurre si intento y escribo una función. SW & AD no funcionan. Las otras llamadas lo hacen.

> 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 

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

+0

¿Qué significa 'i' - ¿quisiste decir' y <- 1' en la primera línea? –

Respuesta

50

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

Aquí hay un ejemplo de cómo puede 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 

Así que tenemos impresión automática. En el bucle que tendríamos que hacer esto:

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

Si desea imprimir más pruebas, entonces sólo les añadir líneas adicionales como en el bucle:

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? Puede hacer que el uso de 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]) 
} 

Podemos entonces mirar los modelos usando

> obj[[1]] 

    Shapiro-Wilk normality test 

data: DF[, y] 
W = 0.9891, p-value = 0.5895 

por ejemplo, o utilizando lapply, que se encarga de establecer el objeto que utilizamos para almacenar el resultados para nosotros:

> obj2 <- lapply(DF, shapiro.test) 
> obj2[[1]] 

    Shapiro-Wilk normality test 

data: X[[1L]] 
W = 0.9891, p-value = 0.5895 

Di ahora me querían para extraer los datos y Wp-value, podemos procesar el objeto de almacenar todos los resultados a ext Ract 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 estrellas de significación:

> 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 salida a la pantalla que se tiene que verter ¿mediante?

+0

Muchas gracias, Gavin. No sabía que la "impresión" estaba desactivada en bucles y funciones. El doctor no dijo eso. Tampoco estaba familiarizado con "y en seq_along (obj)". ¡No sabía que podías hacer eso! Tu respuesta es muy útil. –

+0

No sabía sobre 'printCoefmat'. ¡¡Estupendo!! – Rodrigo

32

No es una respuesta nueva, pero además de lo anterior: "flush.consola()" es necesario forzar la impresión que tendrá lugar durante el bucle en lugar de después. La única razón que utilizo de impresión() durante un ciclo es mostrar el progreso, por ejemplo, de la lectura de muchos archivos.

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

Vota por responder la pregunta establecida en el título. Esto debe ser editado, por lo tanto, el título de estas preguntas no coincide con la pregunta en sí. – aldux

+0

Votando por flush.console() – szeta

4

respuesta fantástico de Gavin Simpson. tomé el último bit de la magia y la convirtió 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) 
} 

a continuación, sólo se puede llamar con su trama de datos sw.df (df)

y si quieres para intentar una transformación: sw.df (log (df))

Cuestiones relacionadas