R语言实战数据科学与R语言数据-R语言-图表-决策-Linux-Python

R语言实战__第6章 基本图形

2017-02-25  本文已影响570人  00e6a8fd618f

第6章 基本图形

分析数据第一件要做的事情就是观察它。对于每个变量,哪些值是最常见的?值域是大是小?是否有不寻常的观测?R中提供了丰富的数据可视化函数。
本章介绍条形图、饼图、扇形图、直方图、核密度图、箱线图、小提琴图和点图的方法。以便更好地理解数据,并能够与他人沟通这些理解方式。

6.1 条形图

条形图通过垂直的或水平的条形展示了类别型变量的分布(频数)。函数barplot( )的最简单用于是:
barplot (height)
其中的height是一个向量或一个矩阵。
接下来的示例中,将绘制一项探索类风湿性关节炎新疗法研究的结果。数据包含在vcd包分发的Arthritis数据框中。

6.1.1 简单的条形图

若heigth是一个向量,则它的值就确定了个条形的高度,并将绘制一副垂直的条形图。使用选项horiz=TRUE则会生成一副水平条形图。可以添加标注选项。选项main可添加一个图形标题,选项xlab和ylab则会分别添加x轴和y轴标签。
在关节炎研究中,变量Improved记录了每对接受了药物治疗的病人的治疗结果。

> library(vcd)
载入需要的程辑包:grid
> conts <- table(Arthritis$Improved)
> conts

  None   Some Marked 
    42     14     28 

这里可以看到28位明显改善,14人部分改善,42人没有改善。
代码清单6-1 简单的条形图

> barplot (conts, main="Simple Bar Plot", xlab="Improvement", ylab="Frequency")
> #conts绘制垂直条形图,标题,x标签,y标签
> barplot (conts, main="Horizontal Bar Plot", xlab="Frequercy", ylab="Improvement", horiz=TRUE)
> #水平条形图

6.1.4节中将介绍微调标签的方法,防止重叠。
若要绘制的类别变量是一个因子或有序型因子,就可以使用函数plot( )快速创建一副垂直条形图。由于Arthritis$Improved是一个因子,所以代码:

plot (Arthritis$Improved, main="Simple Bar Plot", xlab="Improvement", ylab="Frequency")

与代码清单6-1结果相同,无需使用table( )函数将其表格化。

6.1.2 堆砌条形图和分组条形图

如果heigth是一个矩阵而不是一个向量,则绘图结果将是一副堆砌条形图或分组条形图。若beside=FALSE(默认值),则矩阵中的每一列都将生成图中的一个条形,若beside=TRUE,则矩阵中的每一列都表示一个分组,各列中的值将并列而不是堆砌。
代码清单6-2 堆砌条形图和分组条形图

> library(vcd)
> counts <- table(Arthritis$Improved, Arthritis$Treatment)
> counts
> barplot(counts, main="Stacked Bar Plot", xlab="Treatment", ylab="Frequenty", col=c("red", "yellow", "green"), legend=rownames(counts))
> #counts数据源,主题,x轴标签,y轴标签,颜色(3重),图例(对应行或列标签)
> barplot(counts, main="Grouped Bar Plot", xlab="Treatment", ylab="Frequency", col=c("red", "yellow", "green"), legend=rownames(counts), beside=TRUE)
beside区别.png

左图堆砌条形图(beside=FALSE),有图分组条形图(beside=TRUE)。
legend.text为图例提供各条形的标签(仅在height为矩阵时有用)。

6.1.3 均值条形图

条形图不一定基于计算数据或频率数据。可以使用数据整合函数并将结果传递给barplot( )函数,创建表示均值、中位数、标准差等的条形图。下面提供示例:
代码清单6-3 排序后均值的条形图

> states <- data.frame(state.region, state.x77)
> states
> means <- aggregate(states$Illiteracy, by=list(state.region), FUN=mean)
> #数据整理,region分类后对Illiteracy计算平均
> means
        Group.1        x
1     Northeast 1.000000
2         South 1.737500
3 North Central 0.700000
4          West 1.023077
> means <- means[order(means$x), ]
> #按照x排序
> means
        Group.1        x
3 North Central 0.700000
1     Northeast 1.000000
4          West 1.023077
2         South 1.737500
> barplot(means$x, names.arg=means$Group.1)
> #绘图,标签名取Group.1
> title("Mean Illiteracy Rate")

6.1.4 条形图的微调

条形图中条形标签可以使用参数cex.names减小字号。将其指定为小于1的值可以缩小标签的大小。可选的参数names.arg允许指定一个字符向量作为条形的标签名。同样可以使用图形参数辅助调整文本间隔。
代码清单6-4 为条形图搭配标签

> par(las=2) #设置标签平行于x轴
> par(mar=c(5, 8, 4, 2)) #下左右上页边距
> counts <- table(Arthritis$Improved) #获取数据
Error in table(Arthritis$Improved) : 找不到对象'Arthritis'
> library(vcd)
载入需要的程辑包:grid
> counts <- table(Arthritis$Improved) #获取数据
> barplot(counts, main="Treatment Outcome", horiz=TRUE, cex.names=0.8, names.arg=c("No Improvement", "Some Improvement", "Marked Improvement"))
> #标题,水平条形图,标题字号0.8,标签名称

6.1.5 棘状图

棘状图(spinogram)对堆砌条形图进行了重缩放,这样每个条形的高度均为1,每一段的高度即表示比例。棘状图可有vcd包中的函数spine( )绘制。一下代码生成一副简单的棘状图:

> library(vcd)
载入需要的程辑包:grid
> counts <- table(Arthritis$Improved) #获取数据
> barplot(counts, main="Treatment Outcome", horiz=TRUE, cex.names=0.8, names.arg=c("No Improvement", "Some Improvement", "Marked Improvement")
+ )
> library(vcd)
> attach(Arthritis)
> counts <- table(Treatment, Improved)
> spine(counts, main="Spinogram Example")
> #获取棘状图
棘状图.png

除了条形图,饼图也是一种展示类别型变量分布的流行工具。

6.2 饼图

饼图在商业界无处不在,但相对于面积,人们对长度的判断更精确,因此R中饼图的选项十分有限。
饼图可以使用以下函数创建:
pie(x, labels)
其中x为非负数值向量,表示每个扇形的面积,而labels则表示个扇形标签的字符型向量。
代码清单6-5 饼图

> 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")
> #绘制饼图,数据源slices,标签为lbls,标题
> pct <- round(slices/sum(slices)*100) #round四舍五入
> pct
[1] 22 27 34 17
> lbls <- paste(lbls, pct)
> lbls <- paste(lbls, "%", sep="")
> lbls
[1] "US 22%"        "UK 27%"        "Australia 34%" "Germany 17%"  
[5] "France 22%"   
> pie(slices, labels = lbls, col=rainbow(length(lbls)), main="Pie Chart with Precentages")
> #饼图
> library(plotrix)
> pie3D(slices, labels=lbls, explode=0.1, main="3D Pie Chart")
Error in if (labelsep < minsep) { : 需要TRUE/FALSE值的地方不可以用缺少值
> #生成3D饼图
> mytable <- table(state.region)
> lbls <- paste(names(mytable), "\n", mytable, sep="")
> pie(mytable, labels = lbls, main="Pie Chart form a dataframe\n (with sample sizes)")
6-5饼图结果.png

饼图让比较各扇形变得困难(除非这些值被附加在标签上)。为此饼图变种之一扇形图(fan plot)提供了一种同时展示相对数量和相互差异的方法。在R中,扇形图通过plotrix包中的fan.plot( )函数实现。

> library(plotrix)
> slices <- c(10, 12.4, 16, 8)
> lbls <- c("US", "UK", "Australia", "Germany", "France")
> fan.plot(slices, labels = lbls, main="Fan Plot")
扇形图.png

在一副扇形图中,各个扇形相互叠加,并对半径做了修改,这样所有扇形都是可见的。

6.3 直方图

直方图描述的是连续型变量的分布。直方图通过在X轴上将值域分割为一定数量的组,在Y轴上显示相应值的频数,展示了连续型变量的分布。可以通过使用如下函数创建直方图:
hist(x)
其中x是一个由数据值组成的数值向量。参数freq=FALSE表示根据概率密度而不是频数绘制图形。参数breaks用于控制组的数量。在定义直方图的单元时,默认将生成等距分布。
代码清单6-6 直方图

> par(mfrow=c(2,2))
> #图形排列方式
> hist(mtcars$mpg, breaks=12, col="red", xlab="Miles Per Gallon", main="Histogram, rug plot, density curve")
> #直方图,breaks分组
> hist(mtcars$mpg)
> #简单直方图
> hist(mtcars$mpg, freq=FALSE, breaks=12, ccl="red", xlab="Miles Per Gallon", main="Histogram, rug plot ,density curve")
> rug(jitter(mtcars$mpg))
> #轴须图,在轴旁边出现一些小线段,jitter是加噪函数
> lines(density(mtcars$mpg), col="blue", lwd=2)
> #绘制density曲线
> 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 <- dnrom(xfit, mean=mean(x), sd=sd(x))
错误: 没有"dnrom"这个函数
> 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()
> #盒型
6-6直方图.png

图三为轴须图(rug plot)。如果数据中有许多结(相同的值),可以使用入如下代码将轴须图的数据打散:
rug(jitter(mtcars$mpag, amount=0.01))
避免重叠的点产生影响。轴须图可以说明频数,密集表示多。

6.4 核密度图

核密度估计是用于估计随机变量概率密度函数的一种非参数方法。总体上将核密度图不失为一种用来观察连续型变量分布的有效方法。绘制密度图的方法(不叠加到另一幅图上方)为:
plot(density(x))
其中x是一个数值型向量。由于plot( )函数会创建一副新的图形,所以要向一副已经存在的图形上叠加一条密度曲线,可以使用lines( )函数(如代码清单6-6所示)。
两幅核密度图示例:
代码清单6-7 核密度图

> par(mfrow=c(2,1))
> d <- density(mtcars$mpg) # 密度数据
> plot(d) # 绘图
>
> d <- density(mtcars$mpg)                                  
> plot(d, main="Kernel Density of Miles Per Gallon")       
> polygon(d, col="red", border="blue")                     
> rug(mtcars$mpg, col="brown") 
> #轴须图
6-7.png

核密度图可用于比较组间差异。使用sm包中的sm.density.compare( )函数可以向图形叠加两组或者更多的核密度图。使用格式为:
sm.density.compare(x, factor)
其中的x是一个数值型向量,factor是一个分组变量。代码6-8提供了一个示例,比较了拥有4个、6个或8个汽缸车型的每加仑汽油行驶英里数。
6-8 可比较的核密度图

> par(lwd=2)                                                       
> library(sm)
Package 'sm', version 2.2-5.4: type help(sm) for summary information
> attach(mtcars)
> 
> # create value labels 
> cyl.f <- factor(cyl, levels= c(4, 6, 8),                               
+                 labels = c("4 cylinder", "6 cylinder", "8 cylinder")) 
> 
> # plot densities 
> sm.density.compare(mpg, cyl, xlab="Miles Per Gallon")                
> title(main="MPG Distribution by Car Cylinders")
> 
> # add legend via mouse click
> colfill<-c(2:(2+length(levels(cyl.f)))) 
> cat("Use mouse to place legend...","\n\n")
Use mouse to place legend... 

> legend(locator(1), levels(cyl.f), fill=colfill) 
> detach(mtcars)
6-8 可比较的核密度曲线.png

6.5 箱线图

箱线图(又称为盒须图)通过绘制连续型变量的五数总括,即最小值、下四分位数、中位数、上四分位数以及最大值,描述了连续型变量的分布。箱线图能够显示出可能为离群点的观测。例如:

> boxplot(mtcars$mpg, main="Box plot", ylab="Miles per Gallon")
> #绘制箱线图
> boxplot.stats(mtcars$mpg)
> #输出统计量
$stats
[1] 10.40 15.35 19.20 22.80 33.90

$n
[1] 32

$conf
[1] 17.11916 21.28084

$out
numeric(0)

6.5.1 使用并列箱线图进行跨组比较

箱线图可以展示单个变量或分组变量。使用格式为:
boxplot(formula, data=dataframe)
其中的formula是一个公式,dataframe代表提供数据的数据框(或列表)。一个示例公式为yA,这将为类别型变量A的每个值并列地生成数值型变量y的箱线图。公式yA*B则将为类别型变量A和B所有水平的两两组合生成数值型变量y的箱线图。
添加参数varwidth=TRUE将使箱线图的宽度与其样本大小的平方根成正比。参数horizontal=TRUE反转坐标轴方向。
在以下代码中,使用并列箱线图研究了四缸、六缸、八缸发动机对每加仑汽油行驶的英里数的影响。

> boxplot(mpg ~ cyl, data=mtcars, main="Car Mileage Data", xlab="Number of Cylinders", ylab="Miles Per Gallon")
并列箱线图.png

箱线图灵活多变,通过添加notch=TRUE,可以得到含凹槽的箱线图。若两个箱的凹槽互不重叠,则表明它们的中位数有显著差异。为车型油耗示例创建一副含凹槽的箱线图:

> boxplot(mpg~cyl, data=mtcars, notch=TRUE, varwidth=TRUE, col="red", main="Car Mileage Data", xlab="Number of Cylinders", ylab="Miles Per Gallon")
Warning message:
In bxp(list(stats = c(21.4, 22.8, 26, 30.4, 33.9, 17.8, 18.65, 19.7,  :
  一些槽在折叶点外('box'): 可能是因为notch=FALSE
凹槽箱线图.png

varwidth=TRUE使箱线图的宽度与它们各自的样本大小成正比。

此外,可以为多个分组因子绘制箱线图。代码清单6-9为不同缸数和不同变速箱类型的车型绘制了每加仑汽油行驶英里数的箱线图。同样地,使用col为箱线图着色。注意颜色的循环使用。
代码清单6-9 两个交叉因子的箱线图

> 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")
交叉因子箱线图.png

6.5.2 小提琴图

小提琴图是箱线图与核密度图的结合。可以使用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( )函数要求将绘制的不同组分离到不同变量中
> vioplot(x1, x2, x3, names=c("4 cyl", "6 cyl", "8 cyl"), col="gold")
6-10 小提琴图.png

小提琴图基本上是核密度图以镜像方式在箱线图上的叠加。在图中,白点是中位数,黑色盒型的范围是下四分位点到上四分位点,细黑线表示须。外部形状即为核密度估计。

6.6 点图

点图提供了一种在简单水平刻度上绘制大量有标签值的方法。可以使用dotchart( )函数创建点图,格式为:
dotchatr(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")
点图.png

点图在进过排序并分组变量被不同的符号和颜色区分开的时候最有用。

代码清单6-11 分组、排序、着色后的点图

> 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-11 点图.png

随着数据点增多,点图的实用性随之下降。
点图有许多变种。Hmisc包中也提供了一个带有许多附加功能的点图函数(恰如其分地叫做dotchart2)。

6.7 小结

本章介绍了描述连续型变量和类别型变量的方法。我们看到了如何用条形图和饼图(在较小数据范围情况下)了解类别型变量的分布,以及如何通过堆砌条形图和分组条形图理解不同类别型输出的组间差异。
后续章节中,将会对从单变量拓展到双变量和多变量图形中,用图形刻画许多变量间关系,使用的方法包括散点图、多组折线图、马赛克图、相关图、lattice图形,等等。


——2017.2.25
——工作室510

上一篇 下一篇

猜你喜欢

热点阅读