《ggplot2:資料分析與圖形藝術》
qplot文法總結及繪圖練習
> library(ggplot2)
1,基本繪圖文法
> dsmall <- diamonds[sample(nrow(diamonds), 100), ]
#取原始資料的100個随機樣本
雙繪圖(兩種不同的圖層繪制到一張裡面)
将geom_bar和geom_line繪制到同一張圖中,往往會利用如下方法:
ggplot(msg)+geom_bar(aes(x=position, y=average_AF), stat="identity")+geom_line(aes(x=position, y=sample_count)
即直接在ggplot中引用資料集,在bar和line中引用x及y軸的值,但這樣做有時會報錯,報錯内容為
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
這說明barplot和lineplot沒有明确分組,每個組都隻有一個對象,是以不同的圖層要進行不同的分組,修改上面的代碼為:
ggplot(msg)+geom_bar(aes(x=position, y=average_AF, group=1), stat="identity")+geom_line(aes(x=position, y=sample_count, group=2))
這裡設定兩個不同的分組可解決報錯問題
散點圖
> qplot(carat, price, data=diamonds)
> qplot(carat, price, data=diamonds)
預設情況下即可繪制散點圖,預設輸入的前兩個參數分别為x軸的值和y軸的值,data表示繪圖資料。這三個參數屬于必須參數。資料集為dataframe對象,多半是通過檔案讀取内容得到的資料集。
> rt <- read.table('/Users/XXX/Desktop/R_draw/R_read_rable.txt', header=FALSE)
> colnames(rt)=c('average','mean','top','bottom','last','bool')
> rt
average mean top bottom last bool
1 52.0 111.0 830 5 6.2 no
2 57.5 128.9 710 5 7.5 yes
qplot支援将變量的函數作為參數 > qplot(log(carat), log(price), data=diamonds)
> qplot(log(carat), log(price), data=diamonds)
展示的結果是,x及y軸的坐标軸描述和坐标值,均為原值的log值結果
qplot函數的參數同樣可以是已有變量的某種組合 > qplot(carat, x*y*z, data=diamonds)
> qplot(carat, x*y*z, data=diamonds)
展示體積(
x*y*z
,由邊長的乘積大緻計算得到)與重量(carat)之間的關系
2,顔色、大小、形狀和其他圖形屬性
添加圖形屬性
colour函數,改變點圖點的顔色 > qplot(carat, price, data=diamonds, colour=color)
> qplot(carat, price, data=diamonds, colour=color)
同時通過colour函數對不同color值的點進行顔色分組
shape函數,改變點圖點的形狀 > qplot(carat, price, data=diamonds, shape=cut)
> qplot(carat, price, data=diamonds, shape=cut)
同時通過shape函數對不同cut值的點進行形狀分組
I()函數,手動設定固定值圖形屬性 > qplot(carat, price, data=diamonds, colour=I('red'), size=I(2))
> qplot(carat, price, data=diamonds, colour=I('red'), size=I(2))
colour=I(‘red’) 圖形中所有點均為紅色,size=I(2) 圖形中所有點大小均為2
alpha函數,設定透明度 > qplot(carat, price, data=diamonds, alpha=I(1/10))
> qplot(carat, price, data=diamonds, alpha=I(1/10))
alpha函數取值從0(完全透明)到1(完全不透明)
總結:顔色和形狀适合于分類變量,而大小适合于連續變量
3,幾何對象
可通過改變幾何對象(簡寫為geom)繪制其他圖形
- geom=“point”,散點圖,qplot()預設設定;
- geom=“smooth”,拟合一條平滑曲線,并将曲線和标準誤展示在圖中;
- geom=“boxplot”,箱線圖;
- geom=“jitter”,擾動點圖;
- geom=“line”,連線圖,将圖中的點用線段連接配接,從左到右;
-
geom=“path”,路徑圖,同樣用線段連接配接,但方向任意;
下面四種繪圖,隻有x軸數值,y軸表示count或density
連續變量繪圖:
- geom=“histogram”,直方圖;
- geom=“freqpoly”,頻率多邊形圖;
-
geom=“density”,密度圖;
離散變量繪圖:
- geom=“bar”,條圖。
添加平滑曲線
添加平滑曲線 > qplot(carat, price, data=dsmall, geom=c("point","smooth"))
> qplot(carat, price, data=dsmall, geom=c("point","smooth"))
geom=c(“point”,“smooth”)表示先繪制散點圖,再添加平滑曲線;也可以隻添加平滑曲線geom=c(“smooth”)
se控制标準誤, qplot(carat, price, data=dsmall, geom=c("point","smooth"), se=FALSE)
qplot(carat, price, data=dsmall, geom=c("point","smooth"), se=FALSE)
如果se=FALSE則隻有曲線,沒有标準誤差;se=TRUE則二者都有,預設是TRUE
method選擇不同平滑器, qplot(carat, price, data=dsmall, geom=c("point","smooth"), method="loess")
qplot(carat, price, data=dsmall, geom=c("point","smooth"), method="loess")
method="loess"當n較小時是預設選項,使用的是局部回歸的方法
span改變曲線平滑度, qplot(carat, price, data=dsmall, geom=c("point","smooth"), span=0.2)
qplot(carat, price, data=dsmall, geom=c("point","smooth"), span=0.2)
span函數取值從0(很不平滑)到1(很平滑)
method=“gam”, formula=y~s(x), qplot(carat, price, data=dsmall, geom=c("point","smooth"), method="gam", formula=y~s(x))
qplot(carat, price, data=dsmall, geom=c("point","smooth"), method="gam", formula=y~s(x))
使用 method=“gam”, formula=y~s(x)來調用mgcv包拟合一個廣義可加模型。
> library(mgcv)
這與在lm中使用樣條相類似,但樣條的階數是通過資料估計得到的。
method=“gam”, formula=y~s(x, bs=“cs”), qplot(carat, price, data=dsmall, geom=c("point","smooth"), method="gam", formula=y~s(x, bs="cs"))
qplot(carat, price, data=dsmall, geom=c("point","smooth"), method="gam", formula=y~s(x, bs="cs"))
對于大資料,使用公式formula=y~s(x, bs=“cs”)是資料量超過1000時預設使用的選項。
method="lm"拟合線性模型, qplot(carat, price, data=dsmall, geom=c("point","smooth"), method="lm")
qplot(carat, price, data=dsmall, geom=c("point","smooth"), method="lm")
拟合出一條直線
formula=y~I(x) 表示拟合出一項式函數
formula=y~I(x^2)+x 表示拟合出二項式函數
一項式拟合執行個體:y = kx + b
qplot(x,y,data=name,geom=c(“point”,“smooth”),method=“lm”,
formula=y~I(x)
,se=F)
> lm(name$y ~ I(name$x))
(Intercept) name$x
#截距值,一項式系數值
二項式拟合執行個體:y = ax2 + bx + c
qplot(x,y,data=drow,geom=c(“point”,“smooth”),method=“lm”,
formula=y~I(x^2)+x
,se=F)
> lm(drow$y~I(drow$x^2)+drow$x)
(Intercept) I(drow$x^2) drow$x
#截距值,二項式系數值,一項式系數值
method=“lm”, formula=y~poly(x, 2), qplot(carat, price, data=dsmall, geom=c("point","smooth"), method="lm", formula=y~poly(x, 2))
qplot(carat, price, data=dsmall, geom=c("point","smooth"), method="lm", formula=y~poly(x, 2))
> library(splines)
可以通過制定formula=y~poly(x, 2)來拟合一個二次多項式或加載splines包以使用自然樣條:
formula=y~ns(x, 2)
。第二個參數是自由度:自由度取值越大,曲線的波動也越大。
method="rlm"與lm類似,但采用了一種更穩健的拟合算法。
箱線圖、擾動點圖,x軸是離散變量(用作分組),y軸是各個組别的數值
geom=“jitter”,擾動點圖 > qplot(color, price/carat, data=diamonds, geom="jitter", alpha=I(1/5), colour=I('blue'))
> qplot(color, price/carat, data=diamonds, geom="jitter", alpha=I(1/5), colour=I('blue'))
可通過alpha函數添加透明度,通過colour函數添加顔色
geom=“boxplot”,箱線圖 > qplot(color, price/carat, data=diamonds, geom="boxplot", fill=color)
> qplot(color, price/carat, data=diamonds, geom="boxplot", fill=color)
可通過函數fill=color對不同組别添加顔色
總結:箱線圖資訊較為充分,可顯示出分布的中位數和四分位數;擾動點圖不能顯示,但通過改變擾動點圖的透明度,展示資料密集分布的位置。
直方圖、密度曲線圖
geom=“histogram”,直方圖 > qplot(carat, data=diamonds, geom="histogram")+ylab('count')
> qplot(carat, data=diamonds, geom="histogram")+ylab('count')
直方圖隻有一個x軸
carat
,y軸表示個數即
+ylab('count')
(ylab(),設定y軸的資料名稱),反映carat連續變量在x軸上的各個區間數值的個數并反映在y軸上
binwidth,設定直方圖組距 > qplot(carat, data=diamonds, geom="histogram", binwidth=0.1)+ylab('count')
> qplot(carat, data=diamonds, geom="histogram", binwidth=0.1)+ylab('count')
binwidth設定組距調節直方圖平滑度;值越大組距越大;當組距較大時,圖形能反映資料的總體特征;當組距較小時,能細分區間數值;在繪圖是要嘗試多種組距,以配合圖形反映資料趨勢需要
geom=“density”,密度曲線圖 > qplot(carat, data=diamonds, geom="density")+ylab('count')
> qplot(carat, data=diamonds, geom="density")+ylab('count')
和直方圖描述資訊及作用相似,隻不過用平滑的曲線連接配接。
adjust,設定曲線平滑度 > qplot(carat, data=diamonds, geom="density", adjust=0.1)+ylab('count')
> qplot(carat, data=diamonds, geom="density", adjust=0.1)+ylab('count')
adjust取值越大,曲線越平滑,資料細分越不明顯;取值越小,曲線越曲折,資料細分越明顯
colour
給geom="density"密度曲線圖線條上色, fill
給geom="histogram"直方圖填充顔色
colour
fill
條形圖,意在計算每個水準下觀測數量
geom=“bar”,條形圖 > qplot(color, data=diamonds, geom="bar")+ylab("count")
> qplot(color, data=diamonds, geom="bar")+ylab("count")
條圖隻有一個x軸
color
,計算的是這個離散變量在資料diamonds中出現次數統計
weight,重量權重 > qplot(color, data=diamonds, geom="bar", weight=carat)+scale_y_continuous("carat")
> qplot(color, data=diamonds, geom="bar", weight=carat)+scale_y_continuous("carat")
繪制離散變量color到條形圖,以carat作為color的權重值,是以y軸應該得到的是carat這個權重值的結果,并且通過scale_y_continuous(“carat”)函數得到y軸的标度值及y軸的名稱,意在表示權重值繪制的條形圖是由哪個權重值得到的。
時間序列中的線條圖和路徑圖
geom=“line”,線條圖 > qplot(date, unemploy/pop, data=economics, geom="line")
> qplot(date, unemploy/pop, data=economics, geom="line")
連線都是自左到右
geom=“path”,路徑圖
> year <- function(x) as.POSIXlt(x)$year+1900; qplot(unemploy/pop, uempmed, data=economics, geom="path", colour=year(date))
自1970年開始到2010年内的變化走勢,用漸變的顔色區分不同的時間段,這裡用到了一個year的自行編寫的函數
year <- function(x) as.POSIXlt(x)$year+1900
4,分面
facets=,分面 > qplot(carat, data=diamonds, facets=color ~ ., geom="histogram", binwidth=0.1, xlim=c(0,3))
> qplot(carat, data=diamonds, facets=color ~ ., geom="histogram", binwidth=0.1, xlim=c(0,3))
facets=color ~ .
表示分面,color在diamonds資料集中是離散型變量,是以建議分面的資料為離散型變量;同時建議按照一個次元進行分面,第二次元用
.
(點号)占位;是以這裡color是第一個分面次元,
.
(點号)是第二個分面次元已被忽略;
facets=color ~ cut
表示利用color和cut兩個離散變量進行兩個次元的分面,即用color進行第一個次元的分面後,再将所有資料經過cut進行第二個次元的分面。binwidth=0.1表示設定直方圖的組距,xlim=c(0,3)限定x軸的數值标度為從0到3
facets=color ~ .
表示将分組的每個子圖橫向拉伸
facets=. ~ color
表示将分組的每個子圖縱向拉伸
…density…,密度值的映射 > qplot(carat, ..density.., data=diamonds, facets=color ~ ., geom="histogram", binwidth=0.1, xlim=c(0,3))+ylab("density")
> qplot(carat, ..density.., data=diamonds, facets=color ~ ., geom="histogram", binwidth=0.1, xlim=c(0,3))+ylab("density")
..density..
文法表示将密度而非頻數映射到y軸,并且标注y軸的名稱
…density…,密度值映射的推廣用法 > qplot(carat, ..density.., data=diamonds, geom="histogram")+ylab("density")
限于類似carat資料的連續變量,限于density,histogram密度圖和直方圖
> qplot(carat, ..density.., data=diamonds, geom="histogram")+ylab("density")
> qplot(carat, ..density.., data=diamonds, geom="density")+ylab("density")
密度分布圖本身就是根據密度值進行的劃分,是以縱坐标得到的就是density的值;是以這個表達式的意義和
> qplot(carat, data=diamonds, geom="density")
所表示的意義相同
5,其他選項
xlim, ylim,設定x軸和y軸的顯示區間
它們的取值都是一個長度為2的數值向量,例如xlim=c(0, 20)或ylim=c(-0.9, -0.5)
log,坐标值取對數值
例如:log="x"表示x軸取對數,log="xy"表示x軸和y軸均取對數
main,圖形主題
可以是字元串也可以是表達式,表達式例如(main = expression(beta[1] == 1) ),
expression(frac(price, carat))
xlab, ylab,圖形主題設定x軸和y軸的标簽文字
可以是字元串也可以是表達式
例如:
> qplot(carat, price/carat, data=dsmall, ylab=expression(frac(price, carat)), xlab="Weight (catats)", main="Small diasmonds", xlim=c(.2,1))
6,繪圖練習
已知存在A, B, C, D, E這5類分組,根據下面資料中的結果,統計這5類分組類型分别出現的次數,出現0次的分組也進行統計,并繪制條形圖,并分别對應着這5類分組繪制"red", “orange”, “blue”, “gray”, "black"五種顔色,資料内容見"class.txt"檔案
> class_msg <- read.table('/Users/XXX/Desktop/R_draw/class.txt', header=FALSE)
#讀取檔案
> class_msg
#檔案内容,發現C分組出現次數為0個
··V1
1 A
2 B
3 D
4 D
5 E
6 A
7 B
8 B
9 B
10 B
11 E
12 A
> unlist(class_msg)
#将出現的列資訊轉換成行資訊
V11 V12 V13 V14 V15 V16 V17 V18 V19 V110 V111 V112
A B D D E A B B B B E A
Levels: A B D E
> sum(unlist(class_msg)=='A')
#分别統計各個分類出現的次數
[1] 3
> sum(unlist(class_msg)=='B')
[1] 5
> sum(unlist(class_msg)=='C')
[1] 0
> sum(unlist(class_msg)=='D')
[1] 2
> sum(unlist(class_msg)=='E')
[1] 2
之後将統計的列别和出現的次數繪制成資料框
> draw_msg <- data.frame(class=c('A','B','C','D','E'), weight=c(3,5,0,2,2))
> draw_msg
class weight
1 A 3
2 B 5
3 C 0
4 D 2
5 E 2
另外一種簡單的操作:
> draw_msg <- data.frame(table(class_msg))
> draw_msg
·class_msg Freq
1 A 3
2 B 5
3 D 2
4 E 2
> draw_msg$class_msg <- as.vector(draw_msg$class_msg)
> draw_msg <- rbind(draw_msg[1:2,],c("C",0),draw_msg[3:4,])
> rownames(draw_msg) <- 1:nrow(draw_msg)
> draw_msg
·class_msg Freq
1 A 3
2 B 5
3 C 0
4 D 2
5 E 2
> colnames(draw_msg) <- c('class','weight')
> draw_msg
·class weight
1 A 3
2 B 5
3 C 0
4 D 2
5 E 2
> draw_msg$weight <- as.numeric(draw_msg$weight)
#保證draw_msg$weight這一列是數值而不是字元
進行繪圖操作
> qplot(class, data=draw_msg, geom="bar", weight=weight)
#通過這條簡單的指令能夠繪制出圖形了
接下來繪制标準的"red", “orange”, “blue”, “gray”, "black"五種顔色圖
> col<-c("A"="red","B"="orange","C"="blue","D"="gray","E"="black")
> qplot(class, data=draw_msg, geom="bar", weight=weight, fill=factor(class))+scale_y_continuous("count")+scale_fill_manual(values=col)
或者
> qplot(class, data=draw_msg, geom="bar", weight=weight, fill=factor(class))+scale_y_continuous("count")+scale_fill_manual(values=c("red","orange","blue","gray","black"))
#将scale_fill_manual的values的值直接以向量形式寫進去
繪制條形圖填充顔色一定要用fill,另外fill=factor(class),利用顔色填充分組是不可缺的,scale_fill_manual(values=col)記得是manual和其中的values
geom_bar() + coord_flip() #可将條形圖橫行擺放
reorder用在繪圖中,比如ggplot中繪條形圖,可使x軸按y軸數值大小排序;比如橫軸為class,縱軸為hwy,可寫為:aes(x=reorder(class,hwy), y=hwy)