使用 R 计算由两个不同列分组的列中的出现次数
Counting number of occurrences in a column which is grouped by two different columns using R
以下为原文data.frame
ID Date Type
123 2011-Jan A
123 2011-Jan A
123 2011-Jan A
123 2011-Jan B
123 2011-Jan B
123 2011-Jan C
123 2011-Mar X
123 2011-Mar X
345 2011-Jan A
345 2011-Jan A
345 2011-Jan X
345 2011-Jan X
456 2011-Mar Y
789 2011-Mar z
所需的输出有 5 个新列,它们分别具有列类型的第一个最大计数 (Type_1
)、列类型的第二个最大计数 (Type_2
)。下面是所需的输出
ID Date Type_1 Type_2 Type_3 Type_4 Type_5
123 2011-Jan A B C NA NA
123 2011-Mar X NA NA NA NA
345 2011-Jan A NA NA NA NA
345 2011-Jan X NA NA NA NA
456 2011-Mar Y NA NA NA NA
789 2011-Mar z NA NA NA NA
在一个关于 ID-345 和 Date-2011-Jan 的案例中。实际上有两种类型(A 和 X)具有相似的计数。因此,将创建两个新的观察结果。
这是 data.table
的解决方案:
library(data.table)
setDT(x)[,{x<-table(Type)
as.list(names(x[order(-x)])[1:5])},by=.(ID,Date)]
ID Date Type_1 Type_2 Type_3 Type_4 Type_5
1: 123 2011-Jan A B C NA NA
2: 123 2011-Mar X NA NA NA NA
3: 345 2011-Jan A X NA NA NA
4: 456 2011-Mar Y NA NA NA NA
5: 789 2011-Mar z NA NA NA NA
基本思想是,您想要的是在每个 ID
-Date
对中生成的已排序 table
的名称。我们使用 [1:5]
强制切断任何更长的 tables 并用 NA
填充任何较短的 tables 。就我个人而言,我必须经常处理已排序的 table,因此我编写了一个函数来生成已排序的 table,在这种情况下,这可以更简洁地完成,并且只需要一行——也许对你来说是一个练习挥舞你的排骨。
也可以用 dcast
这样做:
dcast(x[,.N,by=.(ID,Date,Type)][order(ID,Date,-N),
I:=paste0("Type_",1:.N),
by=.(ID,Date)],
ID+Date~I,value.var="Type")
ID Date Type_1 Type_2 Type_3
1: 123 2011-Jan A B C
2: 123 2011-Mar X NA NA
3: 345 2011-Jan A X NA
4: 456 2011-Mar Y NA NA
5: 789 2011-Mar z NA NA
以下为原文data.frame
ID Date Type
123 2011-Jan A
123 2011-Jan A
123 2011-Jan A
123 2011-Jan B
123 2011-Jan B
123 2011-Jan C
123 2011-Mar X
123 2011-Mar X
345 2011-Jan A
345 2011-Jan A
345 2011-Jan X
345 2011-Jan X
456 2011-Mar Y
789 2011-Mar z
所需的输出有 5 个新列,它们分别具有列类型的第一个最大计数 (Type_1
)、列类型的第二个最大计数 (Type_2
)。下面是所需的输出
ID Date Type_1 Type_2 Type_3 Type_4 Type_5
123 2011-Jan A B C NA NA
123 2011-Mar X NA NA NA NA
345 2011-Jan A NA NA NA NA
345 2011-Jan X NA NA NA NA
456 2011-Mar Y NA NA NA NA
789 2011-Mar z NA NA NA NA
在一个关于 ID-345 和 Date-2011-Jan 的案例中。实际上有两种类型(A 和 X)具有相似的计数。因此,将创建两个新的观察结果。
这是 data.table
的解决方案:
library(data.table)
setDT(x)[,{x<-table(Type)
as.list(names(x[order(-x)])[1:5])},by=.(ID,Date)]
ID Date Type_1 Type_2 Type_3 Type_4 Type_5
1: 123 2011-Jan A B C NA NA
2: 123 2011-Mar X NA NA NA NA
3: 345 2011-Jan A X NA NA NA
4: 456 2011-Mar Y NA NA NA NA
5: 789 2011-Mar z NA NA NA NA
基本思想是,您想要的是在每个 ID
-Date
对中生成的已排序 table
的名称。我们使用 [1:5]
强制切断任何更长的 tables 并用 NA
填充任何较短的 tables 。就我个人而言,我必须经常处理已排序的 table,因此我编写了一个函数来生成已排序的 table,在这种情况下,这可以更简洁地完成,并且只需要一行——也许对你来说是一个练习挥舞你的排骨。
也可以用 dcast
这样做:
dcast(x[,.N,by=.(ID,Date,Type)][order(ID,Date,-N),
I:=paste0("Type_",1:.N),
by=.(ID,Date)],
ID+Date~I,value.var="Type")
ID Date Type_1 Type_2 Type_3
1: 123 2011-Jan A B C
2: 123 2011-Mar X NA NA
3: 345 2011-Jan A X NA
4: 456 2011-Mar Y NA NA
5: 789 2011-Mar z NA NA