2011-08-25 5 views
9

¿Cuál es la mejor manera de determinar un factor o crear un nuevo campo de categoría basado en una serie de campos booleanos? En este ejemplo, necesito contar la cantidad de combinaciones únicas de medicamentos.Cómo contar el número de combinaciones de datos booleanos en R

> MultPsychMeds 
     ID OLANZAPINE HALOPERIDOL QUETIAPINE RISPERIDONE 
    1 A   1   1   0   0 
    2 B   1   0   1   0 
    3 C   1   0   1   0 
    4 D   1   0   1   0 
    5 E   1   0   0   1 
    6 F   1   0   0   1 
    7 G   1   0   0   1 
    8 H   1   0   0   1 
    9 I   0   1   1   0 
    10 J   0   1   1   0 

Quizás otra forma de decirlo es que tengo que pivotar o cruzar las parejas. Los resultados finales deben ser algo como:

Combination   Count 
OLANZAPINE/HALOPERIDOL  1 
OLANZAPINE/QUETIAPINE  3 
OLANZAPINE/RISPERIDONE  4 
HALOPERIDOL/QUETIAPINE  2 

Esta trama de datos se puede replicar en R con:

MultPsychMeds <- structure(list(ID = structure(1:10, .Label = c("A", "B", "C", 
"D", "E", "F", "G", "H", "I", "J"), class = "factor"), OLANZAPINE = c(1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 0L), HALOPERIDOL = c(1L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L), QUETIAPINE = c(0L, 1L, 1L, 1L, 
0L, 0L, 0L, 0L, 1L, 1L), RISPERIDONE = c(0L, 0L, 0L, 0L, 1L, 
1L, 1L, 1L, 0L, 0L)), .Names = c("ID", "OLANZAPINE", "HALOPERIDOL", 
"QUETIAPINE", "RISPERIDONE"), class = "data.frame", row.names = c(NA, 
-10L)) 
+2

+1 para proporcionar los datos. Sin embargo, creo que debes actualizar tu título, ya que parece que no hay booleanos (lógicos) involucrados, ni hay ninguna 'conversión' en curso. ¿Puedes revisarlo como "contar el número de co-ocurrencias" o similar? –

+0

Gracias. Revisado el título para que coincida con la pregunta real. Con respecto a Boolean, los datos brutos incluyen 0 para FALSE y 1 para TRUE y R está estableciendo esas variables en enteros al cargar desde archivos .csv. ¿Este proceso sería mejor si primero se convirtieran a variables lógicas? – Rollie

+1

Creo que la referencia a boolean es buena e intuitiva, R equivale a 1 y TRUE a ser uno y el mismo que yo sepa (puede haber casos en que esto no sea cierto). Por ejemplo, '> 1 == TRUE [1] TRUE' – Chase

Respuesta

8

Aquí hay una aproximación utilizando los reshape y plyr paquetes:

library(reshape) 
library(plyr) 

#Melt into long format 
dat.m <- melt(MultPsychMeds, id.vars = "ID") 
#Group at the ID level and paste the drugs together with "/" 
out <- ddply(dat.m, "ID", summarize, combos = paste(variable[value == 1], collapse = "/")) 

#Calculate a table 
with(out, count(combos)) 

         x freq 
1 HALOPERIDOL/QUETIAPINE 2 
2 OLANZAPINE/HALOPERIDOL 1 
3 OLANZAPINE/QUETIAPINE 3 
4 OLANZAPINE/RISPERIDONE 4 
+0

Esto es muy útil y justo lo que estaba buscando. Gracias – Rollie

5

Solo por diversión, una solución base R (que se puede convertir en un oneliner :-)):

data.frame(table(apply(MultPsychMeds[,-1], 1, function(currow){ 
    wc<-which(currow==1) 
    paste(colnames(MultPsychMeds)[wc+1], collapse="/") 
}))) 
2

Otra forma podría ser:

subset(
    as.data.frame(
     with(MultPsychMeds, table(OLANZAPINE, HALOPERIDOL, QUETIAPINE, RISPERIDONE)), 
     responseName="count" 
    ), 
    count>0 
) 

lo que da

OLANZAPINE HALOPERIDOL QUETIAPINE RISPERIDONE count 
4   1   1   0   0  1 
6   1   0   1   0  3 
7   0   1   1   0  2 
10   1   0   0   1  4 

No es una forma exacta que desee, pero es rápido y sencillo.


No es la abreviatura en plyr package:

require(plyr) 
count(MultPsychMeds, c("OLANZAPINE", "HALOPERIDOL", "QUETIAPINE", "RISPERIDONE")) 
# OLANZAPINE HALOPERIDOL QUETIAPINE RISPERIDONE freq 
# 1   0   1   1   0 2 
# 2   1   0   0   1 4 
# 3   1   0   1   0 3 
# 4   1   1   0   0 1 
Cuestiones relacionadas