获取R中类别列中的实际值

Get the actual values in the category column in R

我有一个看起来像这样的数据框

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) 为什么 "ID" 在输出中消失了?它只是一个空白。我怎样才能得到这样的输出

   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 中实现类似的东西吗?请提出替代方案。我非常感谢你的帮助。

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]

基础 R 和减少并行提示以提高性能:

# 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)

使用 tidyr 以适当形式输入的另一种方法(替换上面的最后 3 行):

require(tidyr)
countsdf <- stack(counts)
countsdf <- separate(data = countsdf,col = ind,into = c('id','set'),sep = '\.',)
spread(data = countsdf,set,values)