我有一个包含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库实现这一目标?非常感谢你。
答案 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))