在數據質量得到保證的前提下,通過繪制圖表、計算某些統計量等手段對數據的分布特征和貢獻度進行分析(帕累托分析),分布分析能夠揭示數據的分布特征和分布類型,對於定量數據,可以做出頻率分布表、繪制頻率分布直方圖顯示分布特征;對於定性數據,可用餅圖和條形圖顯示分布情況。帕累托分析在頻率分布直方圖的基礎上,繪制累積頻率,計算投入的效益。
下面的例子使用vcd包中的Arthritis數據集來做數據的分布分析和帕累托分析。
library(grid) library(vcd) head(Arthritis) ID Treatment Sex Age Improved 1 57 Treated Male 27 Some 2 46 Treated Male 29 None 3 77 Treated Male 30 None 4 17 Treated Male 32 Marked 5 36 Treated Male 46 Marked 6 23 Treated Male 58 Marked
一,定量數據的分布分析
對於定量數據,做頻率分布表,繪制頻率分布直方圖。選擇“組數”和“組寬”是做頻率分布分析時遇到的最主要問題,一般按照以下5個步驟來實現:
- 求值域(range):值域 = 最大值 - 最小值
- 決定組距和組數:組距是每個區間的長度,組數 = 值域 / 組距
- 決定組限: 組限是指每個區間的端點,這一步是要確定每組的起點和終點
- 列出頻率分布表
- 繪制頻率分布直方圖
在進行分組時,應遵循的主要原則有:
- 各組之間是互斥的
- 各組的組距相等
(1)制作頻率分布表
按照年齡段來計算頻數,每10年為一個年齡段,統計各個年齡段的人數。由於Arthritis數據集中並沒有該分類變量,這就需要自定義區間,按照分組的間隔來制作頻數分布表。頻率分布表的制作過程在文章《R實戰 第九篇:列聯表和頻數表》中有詳細的描述,不再贅述。
library(grid) library(vcd) labels <- c("< 30", "30 - 40", "40 - 50", "50 - 60", "60 - 70", ">= 70") breaks <- c(1,30,40,50,60,70,100) mytable <- cut(Arthritis$Age, breaks = breaks, labels = labels, right = TRUE ) df <- as.data.frame(table(Age=mytable)) df <- transform(df, cumFreq = cumsum(Freq), FreqRate = prop.table(Freq)) df <- transform(df, CumFreqRate= cumsum(FreqRate)) df <- transform(df,FreqRate=round(FreqRate * 100,2), CumFreqRate= round(CumFreqRate*100,2))
(2)繪制頻率分布直方圖
使用ggplot繪制頻率分布直方圖:
ggplot(data=df, mapping=aes(x=factor(Age),y=FreqRate,group=factor(Age))) + geom_bar(stat="identity")+ labs(title='Age distribution',x='Age range',y='Freq Rate')+ theme_classic()

二,定性數據的分布分析
對於定性變量,通常根據分類來分組,然后統計分組的頻數或頻率,可以采用餅圖或條形圖來描述定性數據的分布:
- 餅圖的每一個扇形部分代表每一類型的百分比或頻數,根據定性變量的類型把餅圖分成幾個部分,每一個部分的大小與每一個類型的頻數成正比;
- 條形圖的高度代表每一類型的百分比或頻數,條形圖的寬度沒有意義。
按照Improved變量的頻數來繪制餅圖和條形圖:
mytable <- with(Arthritis, table(Improved)) df <- as.data.frame(mytable)
1,繪制條形圖
使用geom_bar繪制條形圖:
ggplot(data=df,mapping = aes(x=Improved, y=Freq,fill=Improved)) + geom_bar(stat="identity")+ scale_fill_manual(values=c("#999999", "#E69F00", "#56B4E9"))+ labs(title='Improved Distribution', x='Improved',y='Freq')+ geom_text(stat="identity",aes(y=Freq, label = Freq), size=4, position=position_stack(vjust = 0.5))+ theme_classic()

2,繪制餅圖
使用geom_bar()和 coord_polar() 函數來繪制餅圖,通常情況下,餅圖顯示的是百分比,而直方圖顯示的某個分類的具體數值:
blank_theme <- theme_minimal()+ theme( axis.title.x = element_blank(), axis.title.y = element_blank(), axis.text.x = element_blank(), axis.text.y = element_blank(), panel.border = element_blank(), panel.grid=element_blank(), axis.ticks = element_blank(), plot.title=element_text(size=14, face="bold") ) ggplot(data=df, mapping=aes(x="Improved",y=Freq,fill=Improved))+ geom_bar(stat="identity",width=0.5,position='stack',size=5)+ coord_polar("y", start=0)+ scale_fill_manual(values=c("#999999", "#E69F00", "#56B4E9"))+ blank_theme + geom_text(stat="identity",aes(y=Freq, label = scales::percent(Freq/sum(Freq))), size=4, position=position_stack(vjust = 0.5))

三,帕累托分析
帕累托分析依據的原理是20/80定律,80%的效益常常來自於20%的投入,而其他80%的投入卻只產生了20%的效益,這說明,同樣的投入在不同的地方會產生不同的效益。
怕累托圖的繪制過程是按照貢獻度從高到低依次排列,並繪制累積貢獻度曲線。當樣本數量足夠大時,貢獻度通常會呈現20/80分布。
使用ggplot2繪制的帕累托圖的腳本和圖如下所示:

library(grid) library(vcd) library(ggplot2) library(scales) labels <- c("< 30", "30 - 40", "40 - 50", "50 - 60", "60 - 70", ">= 70") breaks <- c(1,30,40,50,60,70,100) mytable <- cut(Arthritis$Age, breaks = breaks, labels = labels, right = TRUE ) df <- as.data.frame(table(Age=mytable),stringsAsFactors=FALSE) df <- transform(df, FreqRate = prop.table(Freq)) df <- df[order(df$Freq,decreasing =TRUE),] rownames(df) <- seq(nrow(df)) df$Age <- factor(df$Age,levels=df$Age) df$cumRate <- cumsum(df$FreqRate) df$cumRateLable <- as.character(percent(df$cumRate)) df$cumRateLable[1] <- "" ggplot(df, aes(x=Age,y=FreqRate,fill=Age)) + geom_bar(stat="identity",width = 0.7) + geom_text(stat='identity',aes(label=percent(FreqRate)),vjust=-0.5, color="black", size=3)+ scale_y_continuous(name="cum Freq Rate",limits=c(0, 1.1),labels = function(x) paste0(x*100, "%"))+ geom_point(aes(y=cumRate),show.legend=FALSE) + geom_text(stat="identity",aes(label=cumRateLable,y=cumRate), vjust=-0.5, size=3)+ geom_path(aes(y=cumRate, group=1))
四,周期性分析
周期性分析是探索某個變量是否隨着時間變化而呈現出某種周期性變化的趨勢,時間尺度的選擇有年度、季度、月份、周度、天和小時等時間周期。
在進行周期性分析時,不能簡單地以天或月來對數據進行分析,因為,在大多數情況下,人們都是在周一到周五工作,在周六和周日休息,所以,應該根據用戶的行為習慣和業務場景,選擇合適的時間尺度。結合筆者的工作經驗,最常用的周期是周。
對於消費行業數據,節假日是一個必須要考慮的時間點,比如,法定節假日、雙11、618等,還有周末,對於這樣的時間點,數據量會增加很多,沒有節假日和有節假日,數據的差距是非常大的。
對於某些數據,這些特殊的時間點不一定帶來數據的暴增,例如,對於一些技術類網站,由於人們只在工作日訪問,因此訪問量在工作日明顯增大,而在周末、或節假日則會明顯降低。對於這些特殊的時間點,在分析數據時,應考慮周全,特殊處理。
參考文檔:
