2011-09-16 16 views
20

Estoy tratando de crear una tabla de contingencia a partir de un tipo particular de datos. Esto sería factible con bucles, etc., pero dado que mi mesa final contendría más de 10E5 células, estoy buscando una función preexistente.¿Cómo obtengo una tabla de contingencia?

Mis datos iniciales son los siguientes:

PLANT     ANIMAL       INTERACTIONS 
---------------------- ------------------------------- ------------ 
Tragopogon_pratensis Propylea_quatuordecimpunctata   1 
Anthriscus_sylvestris Rhagonycha_nigriventris    3 
Anthriscus_sylvestris Sarcophaga_carnaria     2 
Heracleum_sphondylium Sarcophaga_carnaria     1 
Anthriscus_sylvestris Sarcophaga_variegata     4 
Anthriscus_sylvestris Sphaerophoria_interrupta_Gruppe  3 
Cerastium_holosteoides Sphaerophoria_interrupta_Gruppe  1 

me gustaría crear una tabla como la siguiente:

     Propylea_quatuordecimpunctata Rhagonycha_nigriventris Sarcophaga_carnaria Sarcophaga_variegata Sphaerophoria_interrupta_Gruppe 
---------------------- ----------------------------- ----------------------- ------------------- -------------------- ------------------------------- 
Tragopogon_pratensis 1        0      0     0     0 
Anthriscus_sylvestris 0        3      2     4     3 
Heracleum_sphondylium 0        0      1     0     0 
Cerastium_holosteoides 0        0      0     0     1 

Es decir, todas las especies de plantas en fila, todas las especies animales en las columnas, y a veces no hay interacciones (mientras que mis datos iniciales solo enumeran las interacciones que ocurren).

+2

células 10E5 en una tabla de contingencia !!! ¿Qué análisis estás haciendo? Si está revisando interacciones usando chi-cuadrado, necesita tener al menos 5 observaciones en cada celda. – Ramnath

Respuesta

30

de la base de R, utilice table o xtabs:

with(warpbreaks, table(wool, tension)) 

    tension 
wool L M H 
    A 9 9 9 
    B 9 9 9 

xtabs(~wool+tension, data=warpbreaks) 

    tension 
wool L M H 
    A 9 9 9 
    B 9 9 9 

Los gmodels paquetes tiene una función CrossTable que da una salida similar a lo que los usuarios de SPSS o SAS espera:

library(gmodels) 
with(warpbreaks, CrossTable(wool, tension)) 


    Cell Contents 
|-------------------------| 
|      N | 
| Chi-square contribution | 
|   N/Row Total | 
|   N/Col Total | 
|   N/Table Total | 
|-------------------------| 


Total Observations in Table: 54 


      | tension 
     wool |   L |   M |   H | Row Total | 
-------------|-----------|-----------|-----------|-----------| 
      A |   9 |   9 |   9 |  27 | 
      |  0.000 |  0.000 |  0.000 |   | 
      |  0.333 |  0.333 |  0.333 |  0.500 | 
      |  0.500 |  0.500 |  0.500 |   | 
      |  0.167 |  0.167 |  0.167 |   | 
-------------|-----------|-----------|-----------|-----------| 
      B |   9 |   9 |   9 |  27 | 
      |  0.000 |  0.000 |  0.000 |   | 
      |  0.333 |  0.333 |  0.333 |  0.500 | 
      |  0.500 |  0.500 |  0.500 |   | 
      |  0.167 |  0.167 |  0.167 |   | 
-------------|-----------|-----------|-----------|-----------| 
Column Total |  18 |  18 |  18 |  54 | 
      |  0.333 |  0.333 |  0.333 |   | 
-------------|-----------|-----------|-----------|-----------| 
+0

¿Puede explicar qué significan esos números con los decimales? Usé gmodels para crear tablas de contingencia y el único argumento que establecí en TRUE fue prop.c (es decir, todo lo demás se estableció en FALSE).Aún obtengo un número adicional que se muestra junto con los porcentajes de las columnas y el valor real de n para la celda ... y no puedo por la vida de averiguar qué es (y sí, he buscado mucho en cómo interpretar la salida!). Gracias. – AHegde

+2

Su respuesta está en el producto anterior. En la parte superior de la salida hay un cuadro llamado 'Contenido de celda'. Explica el significado de cada número, es decir, chi-cuadrado y varias fracciones de filas y columnas. – Andrie

9

el paquete reshape debería hacer el truco.

> library(reshape) 

> df <- data.frame(PLANT = c("Tragopogon_pratensis","Anthriscus_sylvestris","Anthriscus_sylvestris","Heracleum_sphondylium","Anthriscus_sylvestris","Anthriscus_sylvestris","Cerastium_holosteoides"), 
        ANIMAL= c("Propylea_quatuordecimpunctata","Rhagonycha_nigriventris","Sarcophaga_carnaria","Sarcophaga_carnaria","Sarcophaga_variegata","Sphaerophoria_interrupta_Gruppe","Sphaerophoria_interrupta_Gruppe"), 
        INTERACTIONS = c(1,3,2,1,4,3,1), 
        stringsAsFactors=FALSE) 

> df <- melt(df,id.vars=c("PLANT","ANIMAL"))  
> df <- cast(df,formula=PLANT~ANIMAL) 
> df <- replace(df,is.na(df),0) 

> df 
        PLANT Propylea_quatuordecimpunctata Rhagonycha_nigriventris 
1 Anthriscus_sylvestris        0      3 
2 Cerastium_holosteoides        0      0 
3 Heracleum_sphondylium        0      0 
4 Tragopogon_pratensis        1      0 
    Sarcophaga_carnaria Sarcophaga_variegata Sphaerophoria_interrupta_Gruppe 
1     2     4        3 
2     0     0        1 
3     1     0        0 
4     0     0        0 

Todavía estoy encontrar la manera de solucionar el problema order, alguna sugerencia?

+1

Puede reemplazar las últimas tres líneas con solo un comando: cast (PLANT ~ ANIMAL, data = df, value = "INTERACTIONS", fill = 0) – Thierry

+0

Si desea ordenar ese resultado en base al orden de entrada del dataframe , puede usar 'order (unique (df $ PLANT))' en las filas y el análogo obvio en las columnas. Su ejemplo no necesitaba 'unique', pero una versión que tenía entradas múltiples por emparejamiento cuyos valores se sumaron podría necesitarlo. –

5

xtabs en la base de R deben trabajar, por ejemplo:

dat <- data.frame(PLANT = c("p1", "p2", "p2", "p4", "p5", "p5", "p6"), 
        ANIMAL = c("a1", "a2", "a3", "a3", "a4", "a5", "a5"), 
        INTERACTIONS = c(1,3,2,1,4,3,1), 
        stringsAsFactors = FALSE) 

(x2.table <- xtabs(dat$INTERACTIONS ~ dat$PLANT + dat$ANIMAL)) 

    dat$ANIMAL 
dat$PLANT a1 a2 a3 a4 a5 
     p1 1 0 0 0 0 
     p2 0 3 2 0 0 
     p4 0 0 1 0 0 
     p5 0 0 0 4 3 
     p6 0 0 0 0 1 

chisq.test(x2.table, simulate.p.value = TRUE) 

Creo que debería hacer lo que está buscando con bastante facilidad. No estoy seguro de cómo se amplía en términos de eficiencia a una tabla de contingencia 10E5, pero eso podría ser un problema separado estadísticamente.

8

me gustaría señalar que podemos obtener los mismos resultados Andrie publicado sin el uso de la función with:

paquete

R Base

# 3 options 
table(warpbreaks[, 2:3]) 
table(warpbreaks[, c("wool", "tension")]) 
table(warpbreaks$wool, warpbreaks$tension, dnn = c("wool", "tension")) 

    tension 
wool L M H 
    A 9 9 9 
    B 9 9 9 

gmodels paquete:

library(gmodels) 
# 2 options  
CrossTable(warpbreaks$wool, warpbreaks$tension) 
CrossTable(warpbreaks$wool, warpbreaks$tension, dnn = c("Wool", "Tension")) 


    Cell Contents 
|-------------------------| 
|      N | 
| Chi-square contribution | 
|   N/Row Total | 
|   N/Col Total | 
|   N/Table Total | 
|-------------------------| 


Total Observations in Table: 54 


       | warpbreaks$tension 
warpbreaks$wool |   L |   M |   H | Row Total | 
----------------|-----------|-----------|-----------|-----------| 
       A |   9 |   9 |   9 |  27 | 
       |  0.000 |  0.000 |  0.000 |   | 
       |  0.333 |  0.333 |  0.333 |  0.500 | 
       |  0.500 |  0.500 |  0.500 |   | 
       |  0.167 |  0.167 |  0.167 |   | 
----------------|-----------|-----------|-----------|-----------| 
       B |   9 |   9 |   9 |  27 | 
       |  0.000 |  0.000 |  0.000 |   | 
       |  0.333 |  0.333 |  0.333 |  0.500 | 
       |  0.500 |  0.500 |  0.500 |   | 
       |  0.167 |  0.167 |  0.167 |   | 
----------------|-----------|-----------|-----------|-----------| 
    Column Total |  18 |  18 |  18 |  54 | 
       |  0.333 |  0.333 |  0.333 |   | 
----------------|-----------|-----------|-----------|-----------| 
2

Simplemente use la función dcast() del paquete "reshape2":

ans = dcast(df, PLANT~ ANIMAL,value.var = "INTERACTIONS", fill = 0) 

Aquí "PLANTA" estará en la columna de la izquierda, "ANIMALES" en la fila superior, el llenado de la tabla se realizará usando "INTERACCIONES" y los valores "NULOS" se llenarán usando 0.

0

Con dplyr/tidyr:

df <- read.table(text='PLANT     ANIMAL       INTERACTIONS 
       Tragopogon_pratensis Propylea_quatuordecimpunctata   1 
       Anthriscus_sylvestris Rhagonycha_nigriventris    3 
       Anthriscus_sylvestris Sarcophaga_carnaria     2 
       Heracleum_sphondylium Sarcophaga_carnaria     1 
       Anthriscus_sylvestris Sarcophaga_variegata     4 
       Anthriscus_sylvestris Sphaerophoria_interrupta_Gruppe  3 
       Cerastium_holosteoides Sphaerophoria_interrupta_Gruppe  1', header=TRUE) 
library(dplyr) 
library(tidyr) 
df %>% spread(ANIMAL, INTERACTIONS, fill=0) 

#     PLANT Propylea_quatuordecimpunctata Rhagonycha_nigriventris Sarcophaga_carnaria Sarcophaga_variegata Sphaerophoria_interrupta_Gruppe 
# 1 Anthriscus_sylvestris        0      3     2     4        3 
# 2 Cerastium_holosteoides        0      0     0     0        1 
# 3 Heracleum_sphondylium        0      0     1     0        0 
# 4 Tragopogon_pratensis        1      0     0     0        0 
Cuestiones relacionadas