按治疗类型汇总 (count/freq),个人可以接受两种治疗

Summarize (count/freq) by treatment type where individuals could receive both treatments

假设我们有这个数据:

dat<-data.frame(id=c(1,1,2,2,3,4,4,5,6,6),Rx=c(1,2,1,2,1,1,1,2,2,2))

   id Rx
1   1  1
2   1  2
3   2  1
4   2  2
5   3  1
6   4  1
7   4  1
8   5  2
9   6  2
10  6  2

其中 Id 是受试者 ID,Rx 是他们接受的治疗。因此,有重复观察,每个受试者的治疗可能一致也可能不一致。

我希望能够总结出有多少受试者只接受了 Rx 1,只接受了 Rx 2,以及有多少受试者接受了 Rx 1 和 2。

我更喜欢 dplyr 解决方案,但 data.tablebase R 也可以。我想是这样的:

dat %>%
  group_by(id,Rx) %>%
  unique() %>%
  ...something

最终结果应该是这样的:

  Rx    Count
   1        2
   2        2
Both        2

谢谢!

此解决方案不能很好地泛化到超过 2 种治疗方法:

library(dplyr)

dat %>%
  distinct(id, Rx) %>%
  group_by(id) %>%
  mutate(
    trt1 = setequal(1, Rx), # change due to comment from @Marat Talipov
    trt2 = setequal(2, Rx),
    both = setequal(1:2, Rx)
    ) %>%
  ungroup() %>%
  distinct(id) %>%
  summarise_each(funs(sum), trt1:both)

这个解决方案更短并且可以推广到不止一种治疗:

library(stringr)

dat %>%
  group_by(id) %>%
  mutate(
    rx_list = str_c(sort(unique(Rx)), collapse = ",")
    ) %>%
  distinct(id) %>%
  count(rx_list)

这是另一个通用的解决方案

library(dplyr)
dat %>%
  group_by(id) %>%
  summarise(indx = toString(sort(unique(Rx)))) %>%
  ungroup() %>%
  count(indx)

# Source: local data table [3 x 2]
# 
#   indx n
# 1 1, 2 2
# 2    1 2
# 3    2 2

data.table,同样

library(data.table)
setDT(dat)[, .(indx = toString(sort(unique(Rx)))), id][ , .N, indx]

不完全是您指定的输出,但它是基础 R,单行和一般:

 table(do.call(function(...) paste(...,sep="_"),as.data.frame(table(dat)>0)))
 #FALSE_TRUE TRUE_FALSE  TRUE_TRUE 
     2          2          2

如果治疗超过两种,您已经指出了所有可能的组合。