R用百分比计算分组频率table
R calculating grouped frequency table with percentage
给出以下 data.frame
,我想计算 VAR
的每个变量的出现次数以及分组变量 GROUP
这些出现次数的百分比:
GROUP<-c("G1","G2","G1","G2","G3","G3","G1")
VAR<-c("A","B","B","A","B","B","A")
d<-data.frame(GROUP,VAR)
使用 table()
,我得到一个很好的频率 table,计算两个变量的所有组合的出现次数:
d<-as.data.frame(table(d))
GROUP VAR Freq
1 G1 A 2
2 G2 A 1
3 G3 A 0
4 G1 B 1
5 G2 B 1
6 G3 B 2
现在我想通过GROUP
计算VAR
的每个变量的百分比。到目前为止,我将 data.frame 除以 GROUP
并分别计算 G1
、G2
和 G3
的百分比,然后合并。
d.G1<-d[d$GROUP=="G1",]
d.G1$per<-d.G1$Freq/sum(d.G1$Freq)
d.G1
GROUP VAR Freq per
1 G1 A 2 0.6666667
4 G1 B 1 0.3333333
...
d.merge<-rbind(d.G1,d.G2,d.G3)
d.merge
GROUP VAR Freq per
1 G1 A 2 0.6666667
4 G1 B 1 0.3333333
2 G2 A 1 0.5000000
5 G2 B 1 0.5000000
3 G3 A 0 0.0000000
6 G3 B 2 1.0000000
是否有更优雅的解决方案,例如使用 reshape2
包?
使用dplyr
包你可以做:
require(dplyr)
d <- d %>% group_by(GROUP) %>% mutate(per = Freq/sum(Freq))
这个答案来自@lukeA 的评论,如果您只需要百分比,我认为这是一个非常优雅的解决方案:
d<-as.data.frame(prop.table(table(d),1))
使用data.table,您可以按如下方式进行:
library(data.table)
GROUP<-c("G1","G2","G1","G2","G3","G3","G1")
VAR<-c("A","B","B","A","B","B","A")
DT <-data.table(GROUP,VAR)
# Create count
DT1 <- DT[, list(Count=.N), by=.(GROUP, VAR)]
# melt and dcast to get all combinations of GROUP and VAR
# as in your output. You can remove it if all combinations
# not required
DT2 <- dcast(DT1, GROUP ~ VAR)
DT3 <- melt(DT2, id.var="GROUP")
# Replace na values with zero
DT3[,lapply(.SD,function(x){ifelse(is.na(x),0,x)})]
# Create percentage
DT3[, percent:=value/sum(value, na.rm=TRUE), by=GROUP]
我试图将输出保留为您的输出。因此必须进行铸造和熔化。如果不需要,这些可以省略。
给出以下 data.frame
,我想计算 VAR
的每个变量的出现次数以及分组变量 GROUP
这些出现次数的百分比:
GROUP<-c("G1","G2","G1","G2","G3","G3","G1")
VAR<-c("A","B","B","A","B","B","A")
d<-data.frame(GROUP,VAR)
使用 table()
,我得到一个很好的频率 table,计算两个变量的所有组合的出现次数:
d<-as.data.frame(table(d))
GROUP VAR Freq
1 G1 A 2
2 G2 A 1
3 G3 A 0
4 G1 B 1
5 G2 B 1
6 G3 B 2
现在我想通过GROUP
计算VAR
的每个变量的百分比。到目前为止,我将 data.frame 除以 GROUP
并分别计算 G1
、G2
和 G3
的百分比,然后合并。
d.G1<-d[d$GROUP=="G1",]
d.G1$per<-d.G1$Freq/sum(d.G1$Freq)
d.G1
GROUP VAR Freq per
1 G1 A 2 0.6666667
4 G1 B 1 0.3333333
...
d.merge<-rbind(d.G1,d.G2,d.G3)
d.merge
GROUP VAR Freq per
1 G1 A 2 0.6666667
4 G1 B 1 0.3333333
2 G2 A 1 0.5000000
5 G2 B 1 0.5000000
3 G3 A 0 0.0000000
6 G3 B 2 1.0000000
是否有更优雅的解决方案,例如使用 reshape2
包?
使用dplyr
包你可以做:
require(dplyr)
d <- d %>% group_by(GROUP) %>% mutate(per = Freq/sum(Freq))
这个答案来自@lukeA 的评论,如果您只需要百分比,我认为这是一个非常优雅的解决方案:
d<-as.data.frame(prop.table(table(d),1))
使用data.table,您可以按如下方式进行:
library(data.table)
GROUP<-c("G1","G2","G1","G2","G3","G3","G1")
VAR<-c("A","B","B","A","B","B","A")
DT <-data.table(GROUP,VAR)
# Create count
DT1 <- DT[, list(Count=.N), by=.(GROUP, VAR)]
# melt and dcast to get all combinations of GROUP and VAR
# as in your output. You can remove it if all combinations
# not required
DT2 <- dcast(DT1, GROUP ~ VAR)
DT3 <- melt(DT2, id.var="GROUP")
# Replace na values with zero
DT3[,lapply(.SD,function(x){ifelse(is.na(x),0,x)})]
# Create percentage
DT3[, percent:=value/sum(value, na.rm=TRUE), by=GROUP]
我试图将输出保留为您的输出。因此必须进行铸造和熔化。如果不需要,这些可以省略。