條形圖
條形圖通過垂直的或水平的條形展示了類別型變量的分布(頻數)。函數 barplot() 的最簡單用法是:
barplot(height)
其中的 height
是一個向量或一個矩陣漓穿。
在接下來的示例中哀托,我們將繪制一項探索類風濕性關節(jié)炎新療法研究的結果劫恒。數據已包含在隨 vcd 包分發(fā)的 Arthritis 數據框中谷异。由于 vcd 包并沒用包括在R的默認安裝中界拦,請確保在第一次使用之前先安裝它:
install. packages("vcd")
注意吸申,我們并不需要使用 vcd 包來創(chuàng)建條形圖。我們讀入它的原因是為了使用 Arthritis 數據集享甸。但我們需要使用 vcd 包創(chuàng)建6.1.5節(jié)中描述的棘狀圖(spinogram)截碴。
簡單的條形圖
library(vcd)
pdf("test1.pdf")
counts <- table(Arthritis$Improved)
par(mfrow=c(1,2))
barplot(counts,
main="Simple Bar Plot",
xlab="Improvement", ylab="Frequency")
barplot(counts,
main="Horizontal Bar Plot",
xlab="Frequency", ylab="Improvement",
horiz=TRUE)
dev.off()
horiz=TRUE
則會生成一幅水平條形圖
如果標簽很長怎么辦?在6.1.4節(jié)中蛉威,你將看到微調標簽的方法日丹,這樣它們就不會重疊了。
堆砌條形圖和分組條形圖
如果 height 是一個矩陣而不是一個向量蚯嫌,則繪圖結果將是一幅堆砌條形圖或分組條形圖哲虾。若 beside=FALSE (默認值),則矩陣中的每一列都將生成圖中的一個條形齐帚,各列中的值將給出堆砌的“子條”的高度妒牙。若 beside=TRUE ,則矩陣中的每一列都表示一個分組对妄,各列中的值將并列而不是堆砌湘今。
考慮治療類型和改善情況的列聯(lián)表:
> counts <- table(Arthritis$Improved, Arthritis$Treatment)
> counts
Placebo Treated
None 29 13
Some 7 7
Marked 7 21
你可以將此結果繪制為一幅堆砌條形圖或一幅分組條形圖(見代碼清單6-2)。結果如圖6-2
所示剪菱。
# 堆砌條形圖
barplot(counts,
main="Stacked Bar Plot",
xlab="Treatment", ylab="Frequency",
col=c("red", "yellow","green"),
legend=rownames(counts))
# 分組條形圖
barplot(counts,
main="Grouped Bar Plot",
xlab="Treatment", ylab="Frequency",
col=c("red", "yellow", "green"),
legend=rownames(counts), beside=TRUE)
在第3章中摩瞎,我們講解過格式化和放置圖例的方法,以確保最好的效果孝常。請試著重新排布圖例的位置以避免它們和條形產生疊加旗们。
# 修改一下Y軸的范圍即可
pdf("test1.pdf")
counts <- table(Arthritis$Improved, Arthritis$Treatment)
counts
par(mfrow=c(1,2))
x = c(0,10,20,30,40,50,60)
# 堆砌條形圖
barplot(counts,
main="Stacked Bar Plot",
xlab="Treatment", ylab="Frequency",
col=c("red", "yellow","green"),
legend=rownames(counts),
ylim = c(0, 60))
# 分組條形圖
barplot(counts,
main="Grouped Bar Plot",
xlab="Treatment", ylab="Frequency",
col=c("red", "yellow", "green"),
legend=rownames(counts), beside=TRUE,
ylim = c(0, 40))
dev.off()
均值條形圖
條形圖并不一定要基于計數數據或頻率數據。你可以使用數據整合函數并將結果傳遞給barplot() 函數构灸,來創(chuàng)建表示均值上渴、中位數、標準差等的條形圖喜颁。代碼清單6-3展示了一個示例稠氮,結果如圖6-3所示。
> states <- data.frame(state.region, state.x77)
> states
state.region Population Income Illiteracy Life.Exp Murder HS.Grad Frost Area
Alabama South 3615 3624 2.1 69.05 15.1 41.3 20 50708
Alaska West 365 6315 1.5 69.31 11.3 66.7 152 566432
Arizona West 2212 4530 1.8 70.55 7.8 58.1 15 113417
Arkansas South 2110 3378 1.9 70.66 10.1 39.9 65 51945
California West 21198 5114 1.1 71.71 10.3 62.6 20 156361
Colorado West 2541 4884 0.7 72.06 6.8 63.9 166 103766
Connecticut Northeast 3100 5348 1.1 72.48 3.1 56.0 139 4862
Delaware South 579 4809 0.9 70.06 6.2 54.6 103 1982
Florida South 8277 4815 1.3 70.66 10.7 52.6 11 54090
Georgia South 4931 4091 2.0 68.54 13.9 40.6 60 58073
Hawaii West 868 4963 1.9 73.60 6.2 61.9 0 6425
Idaho West 813 4119 0.6 71.87 5.3 59.5 126 82677
Illinois North Central 11197 5107 0.9 70.14 10.3 52.6 127 55748
Indiana North Central 5313 4458 0.7 70.88 7.1 52.9 122 36097
Iowa North Central 2861 4628 0.5 72.56 2.3 59.0 140 55941
Kansas North Central 2280 4669 0.6 72.58 4.5 59.9 114 81787
Kentucky South 3387 3712 1.6 70.10 10.6 38.5 95 39650
Louisiana South 3806 3545 2.8 68.76 13.2 42.2 12 44930
Maine Northeast 1058 3694 0.7 70.39 2.7 54.7 161 30920
Maryland South 4122 5299 0.9 70.22 8.5 52.3 101 9891
Massachusetts Northeast 5814 4755 1.1 71.83 3.3 58.5 103 7826
Michigan North Central 9111 4751 0.9 70.63 11.1 52.8 125 56817
Minnesota North Central 3921 4675 0.6 72.96 2.3 57.6 160 79289
Mississippi South 2341 3098 2.4 68.09 12.5 41.0 50 47296
Missouri North Central 4767 4254 0.8 70.69 9.3 48.8 108 68995
Montana West 746 4347 0.6 70.56 5.0 59.2 155 145587
Nebraska North Central 1544 4508 0.6 72.60 2.9 59.3 139 76483
Nevada West 590 5149 0.5 69.03 11.5 65.2 188 109889
New Hampshire Northeast 812 4281 0.7 71.23 3.3 57.6 174 9027
New Jersey Northeast 7333 5237 1.1 70.93 5.2 52.5 115 7521
New Mexico West 1144 3601 2.2 70.32 9.7 55.2 120 121412
New York Northeast 18076 4903 1.4 70.55 10.9 52.7 82 47831
North Carolina South 5441 3875 1.8 69.21 11.1 38.5 80 48798
North Dakota North Central 637 5087 0.8 72.78 1.4 50.3 186 69273
Ohio North Central 10735 4561 0.8 70.82 7.4 53.2 124 40975
Oklahoma South 2715 3983 1.1 71.42 6.4 51.6 82 68782
Oregon West 2284 4660 0.6 72.13 4.2 60.0 44 96184
Pennsylvania Northeast 11860 4449 1.0 70.43 6.1 50.2 126 44966
Rhode Island Northeast 931 4558 1.3 71.90 2.4 46.4 127 1049
South Carolina South 2816 3635 2.3 67.96 11.6 37.8 65 30225
South Dakota North Central 681 4167 0.5 72.08 1.7 53.3 172 75955
Tennessee South 4173 3821 1.7 70.11 11.0 41.8 70 41328
Texas South 12237 4188 2.2 70.90 12.2 47.4 35 262134
Utah West 1203 4022 0.6 72.90 4.5 67.3 137 82096
Vermont Northeast 472 3907 0.6 71.64 5.5 57.1 168 9267
Virginia South 4981 4701 1.4 70.08 9.5 47.8 85 39780
Washington West 3559 4864 0.6 71.72 4.3 63.5 32 66570
West Virginia South 1799 3617 1.4 69.48 6.7 41.6 100 24070
Wisconsin North Central 4589 4468 0.7 72.48 3.0 54.5 149 54464
Wyoming West 376 4566 0.6 70.29 6.9 62.9 173 97203
# aggregate()函數的使用方法見第五章——數據的整合與重構
> means <- aggregate(states$Illiteracy, by=list(state.region), FUN=mean)
> means
Group.1 x
1 Northeast 1.000000
2 South 1.737500
3 North Central 0.700000
4 West 1.023077
barplot(means$x, names.arg=means$Group.1,
col = "Blue")
title("Mean Illiteracy Rate")
means$x
是包含各條形高度的向量半开,而添加選項 names.arg=means$Group.1
是為了展示標簽隔披。
條形圖的微調
有若干種方式可以微調條形圖的外觀。例如寂拆,隨著條數的增多奢米,條形的標簽可能會開始重疊抓韩。你可以使用參數 cex.names 來減小字號。將其指定為小于1的值可以縮小標簽的大小鬓长≮怂可選的參數 names.arg 允許你指定一個字符向量作為條形的標簽名。你同樣可以使用圖形參數輔助調整文本間隔痢士。
代碼清單6-4給出了一個示例彪薛,輸出如圖6-4所示。
par(mar=c(5,8,4,2))
par(las=2)
counts <- table(Arthritis$Improved)
barplot(counts,
main="Treatment Outcome",
horiz=TRUE,
cex.names=0.8,
names.arg=c("No Improvement", "Some Improvement",
"Marked Improvement"))
par() 函數能夠讓你對R的默認圖形做出大量修改怠蹂。詳情參閱第3章翼悴。
棘狀圖
在結束關于條形圖的討論之前氢烘,讓我們再來看一種特殊的條形圖帖鸦,它稱為棘狀圖(spinogram)咱筛。棘狀圖對堆砌條形圖進行了重縮放,這樣每個條形的高度均為1嫌佑,每一段的高度即表示比例豆茫。棘狀圖可由 vcd 包中的函數 spine() 繪制。以下代碼可以生成一幅簡單的棘狀圖:
library(vcd)
attach(Arthritis)
counts <- table(Treatment, Improved)
spine(counts, main="Spinogram Example")
detach(Arthritis)
輸出如圖6-5所示屋摇。治療組同安慰劑組相比揩魂,獲得顯著改善的患者比例明顯更高。
餅圖
餅圖可由以下函數創(chuàng)建:
pie(x, labels)
其中 x 是一個非負數值向量炮温,表示每個扇形的面積火脉,而 labels 則是表示各扇形標簽的字符型向量。
代碼清單6-5給出了四個示例柒啤,結果如圖6-6所示倦挂。
par(mfrow=c(2, 2))
slices <- c(10, 12,4, 16, 8)
lbls <- c("US", "UK", "Australia", "Germany", "France")
pie(slices, labels = lbls,
main="Simple Pie Chart")
pct <- round(slices/sum(slices)*100)
lbls2 <- paste(lbls, " ", pct, "%", sep="")
pie(slices, labels=lbls2, col=rainbow(length(lbls2)),
main="Pie Chart with Percentages")
library(plotrix)
pie3D(slices, labels=lbls,explode=0.1,
main="3D Pie Chart ")
mytable <- table(state.region)
lbls3 <- paste(names(mytable), "\n", mytable, sep="")
pie(mytable, labels = lbls3,
main="Pie Chart from a Table\n (with sample sizes)")
其中 x 是一個非負數值向量,表示每個扇形的面積担巩,而 labels 則是表示各扇形標簽的字符型向量方援。
代碼清單6-5給出了四個示例,結果如圖6-6所示涛癌。
餅圖讓比較各扇形的值變得困難(除非這些值被附加在標簽上)犯戏。例如,觀察(第一幅)最簡單的餅圖拳话,你能分辨出美國(US)和德國(Germany)的大小嗎先匪?(如果你可以,說明你的洞察力比我好假颇。)為改善這種狀況胚鸯,我們創(chuàng)造了一種稱為扇形圖(fan plot)的餅圖變種骨稿。扇形圖(Lemon& Tyagi笨鸡,2009)提供了一種同時展示相對數量和相互差異的方法姜钳。在R中,扇形圖是通過 plotrix包中的 fan.plot() 函數實現(xiàn)的形耗。
考慮以下代碼和結果圖(圖6-7):
library(plotrix)
slices <- c(10, 12,4, 16, 8)
lbls <- c("US", "UK", "Australia", "Germany", "France")
fan.plot(slices, labels = lbls, main="Fan Plot")
如你所見哥桥,確定扇形圖中扇形的相對大小比餅圖要簡單得多。扇形圖雖然尚未普及激涤,但它仍然是新生力量拟糕。
既然已經講完了餅圖和扇形圖,就讓我們轉到直方圖上吧倦踢。與條形圖和餅圖不同送滞,直方圖描述的是連續(xù)型變量的分布。
直方圖
直方圖通過在x軸上將值域分割為一定數量的組辱挥,在y軸上顯示相應值的頻數犁嗅,展示了連續(xù)型變量的分布∥畹猓可以使用如下函數創(chuàng)建直方圖:
hist(x)
其中的 x 是一個由數據值組成的數值向量褂微。參數 freq=FALSE 表示根據概率密度而不是頻數繪制圖形。參數 breaks 用于控制組的數量园爷。在定義直方圖中的單元時宠蚂,默認將生成等距切分。代碼
清單6-6提供了繪制四種直方圖的代碼童社,繪制結果見圖6-8求厕。
par(mfrow=c(2,2))
hist(mtcars$mpg)
hist(mtcars$mpg,
breaks=12,
col="red",
xlab="Miles Per Gallon",
main="Colored histogram with 12 bins")
hist(mtcars$mpg,
freq=FALSE,
breaks=12,
col="red",
xlab="Miles Per Gallon",
main="Histogram, rug plot, density curve")
rug(jitter(mtcars$mpg))
lines(density(mtcars$mpg), col="blue", lwd=2)
x <- mtcars$mpg
h<-hist(x,
breaks=12,
col="red",
xlab="Miles Per Gallon",
main="Histogram with normal curve and box")
xfit<-seq(min(x), max(x), length=40)
yfit<-dnorm(xfit, mean=mean(x), sd=sd(x))
yfit <- yfit*diff(h$mids[1:2])*length(x)
lines(xfit, yfit, col="blue", lwd=2)
box()
核密度圖
在上節(jié)中,你看到了直方圖上疊加的核密度圖叠洗。用術語來說甘改,核密度估計是用于估計隨機變量概率密度函數的一種非參數方法。雖然其數學細節(jié)已經超出了本書的范疇灭抑,但從總體上講十艾,核密度圖不失為一種用來觀察連續(xù)型變量分布的有效方法。繪制密度圖的方法(不疊加到另一幅圖上方)為:
plot(density(x))
其中的 x 是一個數值型向量腾节。由于 plot() 函數會創(chuàng)建一幅新的圖形忘嫉,所以要向一幅已經存在的圖形上疊加一條密度曲線,可以使用 lines() 函數(如代碼清單6-6所示)
代碼清單6-7給出了兩幅核密度圖示例案腺,結果如圖6-9所示庆冕。
par(mfrow=c(2,1))
d <- density(mtcars$mpg)
# 完全使用默認參數
plot(d)
d <- density(mtcars$mpg)
# 添加標題
plot(d, main="Kernel Density of Miles Per Gallon")
# 將曲線改為藍色,并使用實心紅色填充曲線下方的區(qū)域
polygon(d, col="red", border="blue")
# 添加棕色的軸須圖
rug(mtcars$mpg, col="brown")
箱線圖
箱線圖(又稱盒須圖)通過繪制連續(xù)型變量的五數總括劈榨,即最小值访递、下四分位數(第25百分位數)、中位數(第50百分位數)同辣、上四分位數(第75百分位數)以及最大值拷姿,描述了連續(xù)型變量的分布惭载。箱線圖能夠顯示出可能為離群點(范圍±1.5*IQR以外的值,IQR表示四分位距响巢,即上四分位數與下四分位數的差值)的觀測描滔。例如:
boxplot(mtcars$mpg, main="Box plot", ylab="Miles per Gallon")
生成了如圖6-11所示的圖形。為了圖解各個組成部分踪古,我手工添加了標注含长。
默認情況下,兩條須的延伸極限不會超過盒型各端加1.5倍四分位距的范圍伏穆。此范圍以外的值將以點來表示(在這里沒有畫出)拘泞。
舉例來說,在我們的車型樣本中枕扫,每加侖汽油行駛英里數的中位數是19.2田弥,50%的值都落在了15.3和22.8之間,最小值為10.4铡原,最大值為33.9偷厦。我是如何從圖中如此精確地讀出了這些值呢?執(zhí)行 boxplot.stats(mtcars$mpg) 即可輸出用于構建圖形的統(tǒng)計量(換句話說燕刻,我作弊了)只泼。圖中似乎不存在離群點,而且略微正偏(上側的須較下側的須更長)卵洗。
使用并列箱線圖進行跨組比較
箱線圖可以展示單個變量或分組變量请唱。使用格式為:
boxplot(formula, data=dataframe)
其中的 formula 是一個公式, dataframe 代表提供數據的數據框(或列表)过蹂。一個示例公式為 y ~A 十绑,這將為類別型變量 A 的每個值并列地生成數值型變量 y 的箱線圖。公式 y ~ A*B 則將為類別型變量 A 和 B 所有水平的兩兩組合生成數值型變量 y 的箱線圖酷勺。添加參數 varwidth=TRUE 將使箱線圖的寬度與其樣本大小的平方根成正比本橙。參數horizontal=TRUE 可以反轉坐標軸的方向。
在以下代碼中脆诉,我們使用并列箱線圖重新研究了四缸甚亭、六缸、八缸發(fā)動機對每加侖汽油行駛的英里數的影響击胜。結果如圖6-12所示亏狰。
boxplot(mpg ~ cyl, data=mtcars,
main="Car Mileage Data",
xlab="Number of Cylinders",
ylab="Miles Per Gallon")
在圖6-12中可以看到不同組間油耗的區(qū)別非常明顯。同時也可以發(fā)現(xiàn)偶摔,六缸車型的每加侖汽油行駛的英里數分布較其他兩類車型更為均勻暇唾。與六缸和八缸車型相比,四缸車型的每加侖汽油行駛的英里數散布最廣(且正偏)。在八缸組還有一個離群點策州。箱線圖靈活多變嘲叔,通過添加 notch=TRUE ,可以得到含凹槽的箱線圖抽活。若兩個箱的凹槽互不重疊,則表明它們的中位數有顯著差異(Chambers et al.锰什,1983下硕,p. 62)。以下代碼將為我們的車型油耗示例創(chuàng)建一幅含凹槽的箱線圖:
boxplot(mpg ~ cyl, data=mtcars,
notch=TRUE,
varwidth=TRUE,
col="red",
main="Car Mileage Data",
xlab="Number of Cylinders",
ylab="Miles Per Gallon")
參數 col 以紅色填充了箱線圖汁胆,而 varwidth=TRUE 則使箱線圖的寬度與它們各自的樣本大小成正比梭姓。
在圖6-13中可以看到,四缸嫩码、六缸誉尖、八缸車型的油耗中位數是不同的。隨著汽缸數的減少铸题,油耗明顯降低铡恕。
最后,你可以為多個分組因子繪制箱線圖丢间。代碼清單6-9為不同缸數和不同變速箱類型的車型繪制了每加侖汽油行駛英里數的箱線圖(圖形如圖6-14所示)探熔。同樣地,這里使用參數 col 為箱線圖進行了著色烘挫。請注意顏色的循環(huán)使用诀艰。在本例中,共有六幅箱線圖和兩種指定的顏色饮六,所以顏色將重復使用三次其垄。
mtcars$cyl.f <- factor(mtcars$cyl,
levels=c(4,6,8),
labels=c("4","6","8"))
mtcars$am.f <- factor(mtcars$am,
levels=c(0,1),
labels=c("auto", "standard"))
boxplot(mpg ~ am.f *cyl.f,
data=mtcars,
varwidth=TRUE,
col=c("gold","darkgreen"),
main="MPG Distribution by Auto Type",
xlab="Auto Type", ylab="Miles Per Gallon")
圖6-14再一次清晰地顯示出油耗隨著缸數的下降而減少。對于四缸和六缸車型卤橄,標準變速箱(standard)的油耗更高绿满。但是對于八缸車型,油耗似乎沒有差別窟扑。你也可以從箱線圖的寬度看出棒口,四缸標準變速箱的車型和八缸自動變速箱的車型在數據集中最常見。
小提琴圖
在結束箱線圖的討論之前辜膝,有必要研究一種稱為小提琴圖(violin plot)的箱線圖變種无牵。小提琴圖是箱線圖與核密度圖的結合。你可以使用 vioplot 包中的 vioplot() 函數繪制它厂抖。請在第一次使用之前安裝 vioplot 包茎毁。
vioplot() 函數的使用格式為:
vioplot(x1, x2, ... , names=, col=)
其中 x1, x2, ... 表示要繪制的一個或多個數值向量(將為每個向量繪制一幅小提琴圖)。參數names 是小提琴圖中標簽的字符向量,而 col 是一個為每幅小提琴圖指定顏色的向量七蜘。代碼清單6-10中給出了一個示例谭溉。
library(vioplot)
x1 <- mtcars$mpg[mtcars$cyl==4]
x2 <- mtcars$mpg[mtcars$cyl==6]
x3 <- mtcars$mpg[mtcars$cyl==8]
vioplot(x1, x2, x3,
names=c("4 cyl", "6 cyl", "8 cyl"),
col="gold")
title("Violin Plots of Miles Per Gallon", ylab="Miles Per Gallon",
xlab="Number of Cylinders")
小提琴圖基本上是核密度圖以鏡像方式在箱線圖上的疊加。在圖中橡卤,白點是中位數扮念,黑色盒型的范圍是下四分位點到上四分位點,細黑線表示須碧库。外部形狀即為核密度估計柜与。小提琴圖還沒有真正地流行起來。同樣嵌灰,這可能也是由于普遍缺乏方便好用的軟件導致的弄匕。時間會證明一切。我們將以點圖結束本章沽瞭。與之前看到的圖形不同迁匠,點圖繪制變量中的所有值。
點圖
點圖提供了一種在簡單水平刻度上繪制大量有標簽值的方法驹溃。你可以使用 dotchart() 函數
創(chuàng)建點圖城丧,格式為:
dotchart(x, labels=)
其中的 x 是一個數值向量,而 labels 則是由每個點的標簽組成的向量豌鹤。你可以通過添加參數groups 來選定一個因子芙贫,用以指定 x 中元素的分組方式。如果這樣做傍药,則參數 gcolor 可以控制不同組標簽的顏色磺平, cex 可以控制標簽的大小。這里是 mtcars 數據集的一個示例:
dotchart(mtcars$mpg, labels=row.names(mtcars), cex=.7,
main="Gas Mileage for Car Models",
xlab="Miles Per Gallon")
繪圖結果已在圖6-16中給出拐辽。
圖6-16可以讓你在同一個水平軸上觀察每種車型的每加侖汽油行駛英里數拣挪。通常來說,點圖在經過排序并且分組變量被不同的符號和顏色區(qū)分開的時候最有用俱诸。代碼清單6-11給出了一個示例菠劝,繪圖的結果如圖6-17所示。
x <- mtcars[order(mtcars$mpg),]
x$cyl <- factor(x$cyl)
x$color[x$cyl==4] <- "red"
x$color[x$cyl==6] <- "blue"
x$color[x$cyl==8] <- "darkgreen"
dotchart(x$mpg,
labels = row.names(x),
cex=.7,
groups = x$cyl,
gcolor = "black",
color = x$color,
pch=19,
main = "Gas Mileage for Car Models\ngrouped by cylinder",
xlab = "Miles Per Gallon")
在圖6-17中睁搭,許多特征第一次明顯起來赶诊。你再次看到,隨著汽缸數的減少园骆,每加侖汽油行駛的英里數有了增加舔痪。但你同時也看到了例外。例如锌唾,Pontiac Firebird有8個汽缸锄码,但較六缸的Mercury280C和Valiant的行駛英里數更多夺英。六缸的Hornet 4 Drive與四缸的Volvo 142E的每加侖汽油行駛英里數相同。同樣明顯的是滋捶,Toyota Corolla的油耗最低痛悯,而Lincoln Continental和Cadillac Fleetwood是英里數較低一端的離群點。
在本例中重窟,你可以從點圖中獲得顯著的洞察力载萌,因為每個點都有標簽,每個點的值都有其內在含義巡扇,并且這些點是以一種能夠促進比較的方式排布的扭仁。但是隨著數據點的增多,點圖的實用性隨之下降霎迫。
注意 點圖有許多變種。Jacoby(2006)對點圖進行了非常有意義的討論帘靡,并且提供了創(chuàng)新型應用的R代碼知给。此外, Hmisc 包也提供了一個帶有許多附加功能的點圖函數(恰如其分地叫作 dotchart2 )描姚。
END !