r loops subset p-value

Recorriendo t.tests para subconjuntos de marcos de datos en r



loops subset (3)

Tengo un marco de datos ''math.numeric'' con 32 variables. Cada fila representa un alumno y cada variable es un atributo. Los estudiantes se han colocado en 5 grupos según su calificación final.

Los datos tienen el siguiente aspecto:

head(math.numeric) school sex age address famsize Pstatus Medu Fedu Mjob Fjob reason ... group 1 1 18 2 1 1 4 4 1 5 1 2 1 1 17 2 1 2 1 1 1 3 1 2 1 1 15 2 2 2 1 1 1 3 3 3 1 1 15 2 1 2 4 2 2 4 2 4 1 1 16 2 1 2 3 3 3 3 2 3 1 2 16 2 2 2 4 3 4 3 4 4

Estoy realizando pruebas t en cada variable para el grupo 1 frente a todos los otros grupos para identificar atributos significativamente diferentes con este grupo. Estoy buscando extraer los valores p para cada prueba, tales como:

t.test(subset(math.numeric$school, math.numeric$group == 1), subset(math.numeric$school, math.numeric$group != 1))$p.value t.test(subset(math.numeric$sex, math.numeric$group == 1), subset(math.numeric$sex, math.numeric$group != 1))$p.value t.test(subset(math.numeric$age, math.numeric$group == 1), subset(math.numeric$age, math.numeric$group != 1))$p.value

He estado tratando de descubrir cómo puedo crear un bucle para hacer esto en lugar de escribir cada prueba de una en una. He intentado un bucle for, y lapply, pero hasta ahora no he tenido suerte.

Soy bastante nuevo en esto, por lo que cualquier ayuda sería apreciada.

Courtney


¿Cómo es esto?

pvals <- numeric() #the vector of p values k <- 1 #in case you choose to use a subset not continuing from 1 # "for(i in seq(1,5))" is just doing the pvalues for the first 5 columns. You could do a # list, like "c(1,2,4)" (in place of "seq(1,5)"), to do tests for columns 1, 2, and 4. # To do all of the columns, try "for(i in seq(1,(ncol(math.numeric)-1)))". for(i in seq(1,5)){ # using your code to grab the p-values and store them in the kth element of "pvals" pvals[k] <- t.test(subset(math.numeric[,i], math.numeric$group == 1), subset(math.numeric[,i], math.numeric$group != 1))$p.value #iterating the "pvals" vector entry counter k=k+1 } pvals #printing the p values for each test


Considere dividir el marco de datos por grupo y usar mapply() en las columnas. La salida se convierte en una lista compilada de estadísticas de pruebas: estadística, parámetro, valor p, confid. intervalo, etc.

# FILTER ROWS AND SUBSET NUMERIC COLS group1df <- df[df$group==1, 1:ncol(df)-1] othgroupdf <- df[df$group!=1, 1:ncol(df)-1] # T-TEST FCT tfct <- function(v1, v2){ t.test(v1, v2) } # RUN T-TESTS BY COL, SAVE RESULTS TO LIST ttests <- mapply(tfct, group1df, othgroupdf)


Sus datos de ejemplo no son suficientes para llevar a cabo pruebas t en todos los subgrupos. Por esa razón, tomo el conjunto de datos de iris , que contiene 3 especies de plantas: Setosa, Versicolor y Virginica. Estos son mis grupos. Tendrá que ajustar su código en consecuencia. A continuación, muestro cómo evaluar un grupo versus todos los demás grupos, un grupo versus otro grupo y todas las combinaciones de grupos individuales.

Un grupo versus todos los otros grupos combinados:

Primero, digamos que quiero comparar Versicolor y Virginica con Setosa, es decir, Setosa es mi group 1 con el que se deben comparar todos los demás grupos. Una manera fácil de lograr lo que quieres es lo siguiente:

sapply(names(iris)[-ncol(iris)], function(x){ t.test(iris[iris$Species=="setosa", x], iris[iris$Species!="setosa", x])$p.value }) Sepal.Length Sepal.Width Petal.Length Petal.Width 7.709331e-32 1.035396e-13 1.746188e-69 1.347804e-60

Aquí, he proporcionado los nombres de las diferentes variables en los names(iris) del conjunto de datos names(iris) , excluyendo la columna que indica la variable de agrupación [-ncol(iris)] (ya que es la última columna), como vector para sapply , que pasa el nombres correspondientes como argumentos de la función que he definido.

Un grupo versus cada uno de los otros grupos:

En caso de que quiera hacer comparaciones grupales para todos los grupos, lo siguiente puede ser útil: Primero, cree un marco de datos de todas las combinaciones de variables de grupo x que vaya a hacer, excluyendo la variable de agrupación en sí y el grupo de referencia, por supuesto. Esto se puede lograr mediante:

comps <- expand.grid(unique(iris$Species)[-1], # excluding Setosa as reference group names(iris)[-ncol(iris)] # excluding group column ) head(comps) Var1 Var2 1 versicolor Sepal.Length 2 virginica Sepal.Length 3 versicolor Sepal.Width 4 virginica Sepal.Width 5 versicolor Petal.Length 6 virginica Petal.Length

Aquí, Var1 son las diferentes especies, y Var2 las diferentes variables para las cuales se deben hacer comparaciones. El group 1 referencia group 1 o Setosa está implícito en este caso. Ahora, puedo usar apply para crear las pruebas. Hago esto usando cada fila de comps como argumento con dos elementos, el primero de los cuales indica qué turno de grupo es, y el segundo argumento indica qué variable debe compararse. Estos se utilizarán para subconjugar el marco de datos original.

comps$pval <- apply(comps, 1, function(x) { t.test(iris[iris$Species=="setosa", x[2]], iris[iris$Species==x[1], x[2]])$p.value } )

donde el grupo 1, también conocido como Setosa, está codificado en la función. Esto me da un marco de datos con valores p para todas las combinaciones (con Setosa como grupo de referencia) para que sean fáciles de buscar:

head(comps) Var1 Var2 pval 1 versicolor Sepal.Length 3.746743e-17 2 virginica Sepal.Length 3.966867e-25 3 versicolor Sepal.Width 2.484228e-15 4 virginica Sepal.Width 4.570771e-09 5 versicolor Petal.Length 9.934433e-46 6 virginica Petal.Length 9.269628e-50

Todas las combinaciones de grupos:

Puede expandir lo anterior fácilmente para producir un marco de datos que contenga valores p de pruebas t para cada combinación de grupos. Un enfoque sería:

comps <- expand.grid(unique(iris$Species), unique(iris$Species), names(iris)[-ncol(iris)])

Esto ahora tiene tres columnas. Los dos primeros son los grupos y el tercero la variable:

head(comps) Var1 Var2 Var3 1 setosa setosa Sepal.Length 2 versicolor setosa Sepal.Length 3 virginica setosa Sepal.Length 4 setosa versicolor Sepal.Length 5 versicolor versicolor Sepal.Length 6 virginica versicolor Sepal.Length

Puede usar esto para llevar a cabo las pruebas:

comps$pval <- apply(comps, 1, function(x) { t.test(iris[iris$Species==x[1], x[3]], iris[iris$Species==x[2], x[3]])$p.value } )

Recibo un mensaje de error: ¿qué debo hacer?

t.test puede arrojar un mensaje de error si el tamaño de la muestra es demasiado pequeño o si los valores son constantes para un grupo. Esto es problemático ya que solo puede ocurrir para grupos específicos, y es posible que no sepa de antemano cuál es. Sin embargo, el error interrumpirá toda la llamada a la función para apply , y no podrá ver ningún resultado.

Una forma de evitar esto e identificar los grupos problemáticos es ajustar la función t.test alrededor de dplyr::failwith (ver también ?tryCatch ). Para mostrar cómo funciona esto, considere lo siguiente:

smalln <- data.frame(a=1, b=2) t.test(smalln$a, smalln$b) > Error in t.test.default(smalln$a, smalln$b) : not enough ''x'' observations failproof.t <- failwith(default="Some default of your liking", t.test, quiet = T) failproof.t(smalln$a, smalln$b) [1] "Some default of your liking"

De esa manera, cada vez que t.test arroja un error, obtienes un carácter como resultado y el cálculo continúa con otros grupos. No hace falta decir que también puede establecer el default en un número, o cualquier otra cosa. No tiene que ser un personaje.

Descargo de responsabilidad estadístico: Habiendo dicho todo esto, tenga en cuenta que realizar varias pruebas t no es necesariamente una buena práctica estadística. Es posible que desee ajustar sus valores p para tener en cuenta las pruebas múltiples, o puede usar procedimientos de prueba alternativos que realicen pruebas conjuntas.