如何使用dplyr获取每个组的最佳案例?

时间:2015-11-13 07:24:34

标签: r dplyr

我有一个包含3列的数据表:ID,Type和Count。对于每个ID,我希望在此ID中获得具有前2个Count的Type,并将结果展平为一行。例如,如果我的数据表如下所示:

ID   Type   Count
A    1      8
B    1      3
A    2      5
A    3      2
B    2      1
B    3      4

然后我希望我的输出是两行,如下所示:

ID   Top1Type   Top1TypeCount  Top2Type   Top2TypeCount
A    1          8              2          5
B    3          4              1          3

有谁能告诉我如何使用R中的dplyr库实现这一目标?非常感谢你。

2 个答案:

答案 0 :(得分:5)

最好以长/整齐的格式保存数据。为此,您可以使用:

df1 %>% group_by(ID) %>% top_n(2, Count) %>% arrange(ID)

给出:

      ID  Type Count
  (fctr) (int) (int)
1      A     1     8
2      A     2     5
3      B     1     3
4      B     3     4

当你有关系时,你可以使用切片为每个组选择相同数量的观察结果:

# some example data
df2 <- structure(list(ID = structure(c(1L, 2L, 1L, 1L, 2L, 2L), .Label = c("A", "B"), class = "factor"), 
                      Type = c(1L, 1L, 2L, 3L, 2L, 3L), 
                      Count = c(8L, 3L, 8L, 8L, 1L, 4L)), 
                 .Names = c("ID", "Type", "Count"), class = "data.frame", row.names = c(NA, -6L))

没有slice()

df2 %>% group_by(ID) %>% top_n(2, Count) %>% arrange(ID)

给出:

      ID  Type Count
  (fctr) (int) (int)
1      A     1     8
2      A     2     8
3      A     3     8
4      B     1     3
5      B     3     4

使用slice()

df2 %>% group_by(ID) %>% top_n(2, Count) %>% arrange(ID) %>% slice(1:2)

给出:

      ID  Type Count
  (fctr) (int) (int)
1      A     1     8
2      A     2     8
3      B     1     3
4      B     3     4

使用arrange,您可以确定案例的顺序,从而确定slice选择的案例。以下内容:

df2 %>% group_by(ID) %>% top_n(2, Count) %>% arrange(ID, -Type) %>% slice(1:2)

给出了这个结果:

      ID  Type Count
  (fctr) (int) (int)
1      A     3     8
2      A     2     8
3      B     3     4
4      B     1     3

答案 1 :(得分:3)

使用data.table,我们会转换&#39; data.frame&#39;到&#39; data.table&#39; (setDT(df1)),按ID&#39;分组,我们order&#39;计数&#39;按降序排列前两行(head(.SD, 2))的子集。然后,我们创建一个序列列(&#39; N&#39;),按&#39; ID&#39;和dcast分组来自&#39; long&#39;广泛的&#39;。 data.table dcast可以使用多个value.var列。

library(data.table)#v1.9.6+
DT <- setDT(df1)[order(-Count), head(.SD, 2) , by = ID]
DT[, N:= 1:.N, by = ID]

dcast(DT, ID~paste0('Top', N), 
            value.var=c('Type', 'Count'), fill = 0)
#    ID Type_Top1 Type_Top2 Count_Top1 Count_Top2
#1:  A         1         2          8          5
#2:  B         3         1          4          3

数据

df1 <- structure(list(ID = c("A", "B", "A", "A", "B", "B"), 
Type = c(1L, 
1L, 2L, 3L, 2L, 3L), Count = c(8L, 3L, 5L, 2L, 1L, 4L)), 
.Names = c("ID", 
"Type", "Count"), class = "data.frame", row.names = c(NA, -6L))