我有一个看起来像这样的数据框
ID <- c('D101','D101','D102','D102','D101','D102')
Number <- c(7,31,64,66,8,3)
Category <- c('Set_A','Set_B','Set_C','Set_C','Set_A','Set_A')
df <- data.frame(ID,Number,Category)
df
ID Number Category
1 D101 7 Set_A
2 D101 31 Set_B
3 D102 64 Set_C
4 D102 66 Set_C
5 D101 8 Set_A
6 D102 3 Set_A
现在我得到了类别
的摘要table(df$ID,df$Category)
给了我,
Set_A Set_B Set_C
D101 2 1 0
D102 1 0 2
我的问题是
1)为什么&#34; ID&#34;消失在输出?它只是一片空白。我怎样才能获得这样的输出
ID Set_A Set_B Set_C
D101 2 1 0
D102 1 0 2
2)我想要一个如下所示的输出,显示每个ID的数字。请注意,我会将其应用于更大的数据集。
ID Set_A Set_B Set_C
D101 7,8 31 0
D102 31 0 64,66
我们可以在R中实现这样或类似的东西吗?请提出替代方案。我非常感谢你的帮助。
答案 0 :(得分:4)
reshape2
库有dcast()
函数,有点像table()
,但很棒。
第1部分:
dcast(df, ID~Category, value.var='Number', fun.aggregate=length)
ID Set_A Set_B Set_C
1 D101 2 1 0
2 D102 1 0 2
第2部分:
library(reshape2)
dcast(df, ID~Category, value.var='Number', fun.aggregate=paste0, collapse=',')
ID Set_A Set_B Set_C
1 D101 7,8 31
2 D102 3 64,66
虽然我怀疑后者对于较大的数据集会变得笨拙。
PS:data.table版本总是更快,虽然感觉有点像黑魔法:
library(data.table)
setDT(df)[,lapply(split(Number, Category), toString), by=ID]
答案 1 :(得分:1)
基础R和平行提示下降以获得更高的性能:
.article-sharer {
padding: 0;
position:fixed;
}
另一种与tidyr合适的形式(替换上面的3行):
# split into groups
dflist <- split(df$Number,list(df$ID,df$Category))
# counts
counts <- lapply(dflist,length)
# numbers per id
numbersperid <- lapply(dflist,paste,collapse = ',')
# speed up using
require(parallel)
parLapply()
# put into appropriate form
# probably better to parse element names but this seems to work
countsdf <- data.frame(matrix(counts,nrow = 2)) # 2 could probably be length(levels(df$ID))
names(countsdf) <- levels(df$Category)
countsdf$ID <- unique(df$ID)