在 R 中,有没有办法查看一列中的元素对应于另一列中的特定元素的次数?

In R, is there a way of seeing how many times an element in one column corresponds to specific element in another one?

我有一个 table 可以显示患者到医院就诊的情况。可以看到每次看的是哪位医生,像这样:

Patient <- c("pat_1", " pat_2", " pat_3", " pat_4", " pat_5", " pat_1", " pat_2", " pat_3", " pat_4", " pat_5", " pat_1", " pat_2", " pat_3", " pat_4", " pat_5")
Year <- c(2000, 2000, 2000, 2000, 2000, 2001, 2001, 2001, 2001, 2001, 2002, 2002, 2002, 2002, 2002)
Doctor <- c("A", " A", " B", " B", " C", " A", " A", " B", " C", " C", " A", " B", " C", " B", " C")
Doc.per.pat <- data.frame(Patient, Year, Doctor)

table 大约有 15 万行,其中每个患者可能出现多次(通常每年不止一次)。我想得到每个病人看每个医生的次数的结果,如下所示 table:

Doc.per.patient.outcome <- matrix(c(3,0,0 ,2,1,0 ,0,2,1 ,0,2,1 ,0,0,3), ncol=3, byrow = TRUE)
rownames(Doc.per.patient.outcome) <- gl(5, 1, labels = c(paste("pat", 1:5, sep = "_")))
colnames(Doc.per.patient.outcome) <- c("A", "B", "C")
Doc.per.patient.outcome <- as.table(Doc.per.patient.outcome)
Doc.per.patient.outcome

我完全卡住了。一直在考虑 dplyr 和 "select" into patient and year。然后为每位患者 "count" 或 "table"。然后我会让每个病人都见过的医生。但问题是如何将其转换为 table 或数据框。如果有任何帮助,我将不胜感激!

as.data.frame(table(Patient = Doc.per.pat$Patient, Doctor = Doc.per.pat$Doctor))

由于 OP 引用按年聚合数据,但所需的输出跨年聚合,我们将首先聚合数据,包括 Year 列,然后构建跨年 table 来自年级总结。

要获得包含患者、年份和医生就诊次数的数据框,可以使用 dplyr::summarise()。请注意,我编辑了数据,因此患者 pat_1 在 2000 年两次拜访医生 A,因此汇总的 table 看起来与原始数据不同。

Patient <- c("pat_1", "pat_1", "pat_3", "pat_4", "pat_5", "pat_1", "pat_2", "pat_3", "pat_4", "pat_5", "pat_1", "pat_2", "pat_3", "pat_4", "pat_5")
Year <- c(2000, 2000, 2000, 2000, 2000, 2001, 2001, 2001, 2001, 2001, 2002, 2002, 2002, 2002, 2002)
Doctor <- c("A", "A", "B", "B", "C", "A", "A", "B", "C", "C", "A", "B", "C", "B", "C")
Doc.per.pat <- data.frame(Patient, Year, Doctor)
library(dplyr)
Doc.per.pat %>% group_by(Patient,Year,Doctor) %>% summarise(n = n()) ->aggData
aggData

...输出:

# A tibble: 14 x 4
# Groups:   Patient, Year [14]
   Patient  Year Doctor     n
   <fct>   <dbl> <fct>  <int>
 1 pat_1    2000 A          2
 2 pat_1    2001 A          1
 3 pat_1    2002 A          1
 4 pat_2    2001 A          1
 5 pat_2    2002 B          1
 6 pat_3    2000 B          1
 7 pat_3    2001 B          1
 8 pat_3    2002 C          1
 9 pat_4    2000 B          1
10 pat_4    2001 C          1
11 pat_4    2002 B          1
12 pat_5    2000 C          1
13 pat_5    2001 C          1
14 pat_5    2002 C          1
> 

此时数据位于所谓的 narrow form tidy data 中,其中一行表示患者、年份和医生的独特组合的就诊次数。

Base R 中的聚合解决方案 Year 使用 stats::aggregate() 函数。首先,我们创建一个 Count 向量,我们将其包含在输入数据框中,并在 aggregate() 中求和。

Count <- rep(1,length(Doctor))
Doc.per.pat <- data.frame(Patient, Year, Doctor,Count)
aggData <- aggregate(Count ~ Patient + Year + Doctor, data = Doc.per.pat,FUN="sum")

输出与 dplyr::summarise() 的结果相匹配,因此我们不会在此处重复。

可以使用 xtabs() 或从 summarise() 中删除 Year 列来进一步聚合数据。 xtabs() 版本是:

xtabs(n ~ Patient + Doctor,aggData)

...输出为:

> xtabs(n ~ Patient + Doctor,aggData)
       Doctor
Patient A B C
  pat_1 4 0 0
  pat_2 1 1 0
  pat_3 0 2 1
  pat_4 0 2 1
  pat_5 0 0 3
>

通过使用 knitr::kable() 扩展解决方案,可以生成用于打印的输出 suitable,如下所示。

library(knitr)
kable(xtabs(n ~ Patient + Doctor,aggData))

...以及输出:

|      |  A|  B|  C|
|:-----|--:|--:|--:|
|pat_1 |  4|  0|  0|
|pat_2 |  1|  1|  0|
|pat_3 |  0|  2|  1|
|pat_4 |  0|  2|  1|
|pat_5 |  0|  0|  3|
> 

在阅读 markdown 的 HTML 浏览器或编辑器中查看时,table 看起来像这样。