获取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)
我有一个看起来像这样的数据框
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)