Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to count the number of combinations of boolean data in R

Tags:

r

What is the best way to determine a factor or create a new category field based on a number of boolean fields? In this example, I need to count the number of unique combinations of medications.

   > 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

Perhaps another way to state it is that I need to pivot or cross tabulate the pairs. The final results need to look something like:

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

This data frame can be replicated in R with:

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))
like image 279
Rollie Avatar asked Aug 25 '11 03:08

Rollie


3 Answers

Here's one approach using the reshape and plyr packages:

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
like image 139
Chase Avatar answered Nov 19 '22 13:11

Chase


Just for fun, a base R solution (that can be turned into a oneliner :-) ):

data.frame(table(apply(MultPsychMeds[,-1], 1, function(currow){
    wc<-which(currow==1)
    paste(colnames(MultPsychMeds)[wc+1], collapse="/")
})))
like image 41
Nick Sabbe Avatar answered Nov 19 '22 13:11

Nick Sabbe


Another way could be:

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

which gives

   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

It's not an exact way you want it, but is fast and simple.


There is shorthand in 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
like image 2
Marek Avatar answered Nov 19 '22 12:11

Marek