今天我們學(xué)習(xí)另外一種柱狀圖朽色,堆積柱狀圖,就是把每一個組的量堆積起來畫成一個柱狀圖。
用自帶的一個測試數(shù)據(jù)婆翔。
library(reshape2)
library(ggplot2)
data = datasets::attitude
head(data)
從測試數(shù)據(jù)來看,是一個包含30個樣本掏婶,7個變量的數(shù)據(jù)啃奴。下面我們查看每個樣本的scale是否一樣。先查看一下總和雄妥,我們利用apply函數(shù)最蕾。
apply函數(shù):對矩陣、數(shù)據(jù)框老厌、數(shù)組(二維揖膜、多維)等矩陣型數(shù)據(jù),按行或列應(yīng)用函數(shù)FUN進行循環(huán)計算梅桩,并以返回計算結(jié)果
apply(X, MARGIN, FUN, ...)
X:數(shù)組壹粟、矩陣、數(shù)據(jù)框等矩陣型數(shù)據(jù)
MARGIN: 按行計算或按按列計算宿百,1表示按行趁仙,2表示按列
FUN: 自定義的調(diào)用函數(shù)
statistics = apply(data, 1, sum)
statistics
plot(statistics)
從圖中可以看出每個樣本的sum是不一樣的,如果要畫堆積圖的話垦页,就不一樣的比例了雀费。所以我們轉(zhuǎn)化成百分比來畫。
df = data.frame()
for (n in 1:nrow(data))
{
? df = rbind(df, data[n,]/statistics[n])?
}
statistics = apply(df, 1, sum)
statistics
plot(statistics)
可以看出痊焊,轉(zhuǎn)化成百分比之后盏袄,每個樣本中的scale是一樣的,都是1薄啥。
df$name =paste("c",seq(1,nrow(df),1),sep="")
我們再手動的添加了名字上去辕羽,方面后面做演示。
#作圖前有個很重要的前置動作垄惧,要把寬矩陣轉(zhuǎn)換為長矩陣刁愿。通過melt函數(shù)來實現(xiàn)。melt(短數(shù)據(jù)名稱到逊,id="不做變換的列名"铣口,variable=“自定義”value=“自定義”)。其中variable和value的值可自定義觉壶,默認值為variable和value脑题。
data_plot = melt(df,id = "name")
從data_plot可以看出,變成了短數(shù)據(jù)铜靶,主要是把每一列都轉(zhuǎn)化成了行的形式叔遂。
group = c(rep("g1",6),rep("g2",6),rep("g3",6),rep("g4",6),rep("g5",6))
group2 =rep(group,ncol(data))
level=paste("c",seq(1,nrow(df),1),sep="")
data_plot$group=group2? ?#我們又手動的添加了分組的標(biāo)簽,方面后面操作
data_plot$name=factor(data_plot$name,levels=level)? ?#為了讓按照我們想要的順序排序,我們把name設(shè)置成了因子
ggplot( data_plot, aes( x = name, weight = value, fill = variable))+
geom_bar( position = "stack")
下面就生成了一個基本的堆積圖掏熬。
如果把"stack"改成"dodge",可以變成分組柱狀圖秒梅。
ggplot( data_plot, aes( x = name, weight = value, fill = variable))+
? geom_bar( position = "dodge")
可以手動的改顏色等旗芬,當(dāng)然values里面也可以自定義顏色。
ggplot( data_plot, aes( x = name, weight = value, fill = variable))+
geom_bar( position = "stack")+
scale_fill_manual( values = rainbow(7))
也可以根據(jù)我們設(shè)置的group來分面板來畫捆蜀。
ggplot( data_plot, aes( x = name, weight = value, fill = variable))+
geom_bar( position = "stack",width=0.9)+
scale_fill_manual( values = rainbow(7))+
xlab("people")+
ylab("percent")+
theme_classic()+
theme(text = element_text(size = 15))+
theme(axis.text = element_text(face = "bold"),
? ? ? ? axis.text.x = element_text(angle = 45, hjust = 1))+
facet_wrap(group~.,scales="free_x",nrow = 1)+
theme(strip.background=element_rect(fill = c("blue")))
比如疮丛,如果我們想按照variable占的比例來排序,一般情況下辆它,最多的在最下面誊薄,就需要指定variable為factor了。
order_x =? apply(df[,1:7], 2, sum)? # 查看各列 variable的總和
order_x = order_x[order(order_x, decreasing = F)]? # decreasing = T 代表是倒序
order_x? # 看一下锰茉,是從大到小排著的
# 此時 data_plot數(shù)據(jù)框里面的 variable就按照給定的 levels 排序了
data_plot$variable= factor(data_plot$variable,
? ? ? ? ? ? ? ? ? ? ? ? ? levels = names(order_x) ,?
? ? ? ? ? ? ? ? ? ? ? ? ? ordered = T )
ggplot( data_plot, aes( x = name, weight = value, fill = variable))+
geom_bar( position = "stack",width=0.9)+
scale_fill_manual( values = rainbow(7))+
xlab("people")+
ylab("percent")+
theme_classic()+
theme(text = element_text(size = 15))+
theme(axis.text = element_text(face = "bold"),
? ? ? ? axis.text.x = element_text(angle = 45, hjust = 1))+
facet_wrap(group~.,scales="free_x",nrow = 1)+
theme(strip.background=element_rect(fill = c("blue")))
柱狀圖里面書序就改成我們想要的順序了呢蔫。
其實用我們前面用的boxplot來查看比例更為清晰一點。
ggplot(data_plot, aes( x = variable, y= value, fill = variable))+
geom_boxplot()
library(RColorBrewer)
a <- brewer.pal(7,"Set1")
a <- terrain.colors(7)
a <- heat.colors(7)
a <- topo.colors(7)
ggplot( data_plot, aes( x = name, weight = value, fill = variable))+
geom_bar( position = "stack",width=0.9)+
scale_fill_manual( values = rainbow(7))+
#scale_fill_manual( values = a)+
xlab("people")+
ylab("percent")+
theme_classic()+
theme(text = element_text(size = 15))+
theme(axis.text = element_text(face = "bold"),
? ? ? ? axis.text.x = element_text(angle = 45, hjust = 1))+
facet_wrap(group~.,scales="free_x",nrow = 1)+
theme(strip.background=element_rect(fill = c("gray")))+
scale_y_continuous(expand = c(0,0))? ?#消除Y軸兩端的留白區(qū)域
我們進行了微調(diào)格式以下飒筑,比如可以更換不同的色系等片吊。