如何计算R中布尔数据的组合数

时间:2011-08-25 03:53:08

标签: 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

或许另一种说明方式是我需要对这些对进行旋转或交叉制表。最终结果需要看起来像:

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

此数据框可以在R中复制:

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))

3 个答案:

答案 0 :(得分:8)

以下是使用reshapeplyr软件包的一种方法:

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

答案 1 :(得分:5)

只是为了好玩,一个基本的R解决方案(可以变成一个oneliner :-)):

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

答案 2 :(得分:2)

另一种方式可能是:

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

给出了

   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

这不是你想要的确切方式,但是快速而简单。


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