【r<-基础|实战|绘图】基本图形的绘制

主题:

  • 将变量的分布进行可视化的展示;
  • 通过结果变量进行跨组比较。

条形图

函数barplot()的最简单用法是:

barplot(height)

其中的height是一个向量或者一个矩阵。

接下来示例中,我们绘制一项探索类风湿性关节炎新疗法研究的结果。数据已经包含在随vcd包分发的Arthritis数据框中。(请确保在使用前已经安装vcd包,使用命令install.packages("vcd")

简单条形图

height是一个向量,则它的值就确定了各条形图的高度,并将绘制一幅垂直的条形图。使用选项horiz=TRUE则会生成一幅水平条形图。

在关节研究中,变量Improved记录了对每位接受了安慰剂或药物治疗的病人的治疗结果:

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

  None   Some Marked 
    42     14     28 

我们可以使用一幅垂直或水平的条形图来绘制变量counts。代码如下(交互模式):

> barplot(counts,
+         main="Simple Bar Plot",
+         xlab="Improvement", ylab="Frequency")
> barplot(counts,
+         main="Horizontal Bar Plot",
+         xlab="Frequency", ylab="Improvement",
+         horiz=TRUE)
simple_bar_plot.png
horiz_bar_plot.png

生成因素变量的条形图

若要绘制的类别型变量是一个因子或有序因子,就可以使用函数plot()快速创建一幅垂直条形图,而无需使用table()函数将其表格化。下面的代码同样可以绘制出与上图相同的结果:

> plot(Arthritis$Improved, main="Simple Bar Plot",
+     xlab="Improvement", ylab="Frequency")
> plot(Arthritis$Improved, main="Horizontal Bar plot",
+     xlab="Frequency", ylab="Improvement", horiz=TRUE)

堆砌条形图和分组条形图

如果height是一个矩阵而不是一个向量,则绘图结果将是一幅堆砌条形图分组条形图beside=FALSE设置成堆砌(默认),beside=TRUE设置为分组条形图。代码如下:

> library(vcd)
> counts <- table(Arthritis$Improved, Arthritis$Treatment)
> counts
        
         Placebo Treated
  None        29      13
  Some         7       7
  Marked       7      21
> 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)
stacked_bar_plot.png
grouped_bar_plot.png

注意它是依据数据框的行名来生成分类的。

均值条形图

我们可以使用数据整合函数并将结果传递给barplot()函数,来创建表示均值、中位数、标准差等的条形图。

> states <- data.frame(state.region, state.x77)
> 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
> means <- means[order(means$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)
> title("Mean Illiteracy Rate")

mean_bar_plot.png

注意:使用title()函数与调用plot()时添加main选项是等价的。

条形图的微调

有若干种方式可以微调条形图的外观。具体就是调节一些相关的设置参数,例如cex.name可以用来调整字号。详细参考一些文档。par()函数能够让你对R的默认图形作出大量修改,这里只给出一个示例:

par(mar=c(5, 8, 4, 2))  # 增加y边界大小
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")) # 修改标签文本
treatment_bar_plot.png

棘状图

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

library(vcd)
attach(Arthritis)
counts <- table(Treatment, Improved)
spine(counts, main="Spinogram Example")
detach(Arthritis)
spinogram_plot.png

饼图

多数统计学家不喜欢饼图,更推荐使用条形图或点图。因为相对于面积,人们对长度的判断更精确。(所以在此也不详述了)

饼图可以由下面函数创建:

pie(x, labels)

直方图

直方图展示了连续型变量的分布。可以使用如下函数创建直方图:

hist(x)

x是一个由数据值组成的数值向量。参数freq=FALSE表示根据概率密度而不是频数绘制图形。参数breaks用于控制组的数量。默认等距切分。以下提供绘制四种直方图的代码:

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 plot)是实际数据值的一种一维呈现方式
# 如果数据中有许多的结(相同的值),可以使用下列代码将其数据打散
# rug(jitter(mtcars$mpg, amount=0.01))
rug(jitter(mtcars$mpg))
# 这条密度曲线是一个核密度估计,为数据的分布提供了更加平滑的描述,会在下节具体讲述。
lines(density(mtcars$mpg), col="blue", lwd=2) # 添加轴须图

x <- mtcars$mpg
h <- hist(x,
          breaks=12,
          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()                              # 添加密度曲线和外框

hist_example_plot.png

核密度图

核密度估计是用于估计随机变量概率密度的一种非参数方法,不失为一种用来观察连续型变量分布的有效方法。

绘制密度图的方法(不叠加到另一幅图):

plot(density(x))

如果想要叠加到其他图上,可以使用lines()函数。

核密度图

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")         # 棕色轴须图
density_default_plot.png

可以比较的核密度图

核密度图可以用于比较组间,使用sm包中的sm.density.compare()函数可向图形叠加两组或更多的核密度图。使用格式为:

sm.density.compare(x, factor)

其中x是数值向量,factor是一个分组变量。

library(sm)
attach(mtcars)

# 创建分组因子
# 将数值型向量cyl中的(4,6,8)转换为因子
cyl.f <- factor(cyl, levels=c(4,6,8),
                labels = c("4 cylinder", "6 cylinder", 
                           "8 cylinder"))
# 绘制密度图
sm.density.compare(mpg, cyl, xlabel="Miles Per Gallon")
title(main="MPG Distribution by Car Cylinders")

# 通过鼠标点击添加图例
# 第一个参数locator(1)表示用鼠标点击放置图例的位置;第二个参数是由标签组成的字符向量,第三个参数值使用向量colfill为cyl.f的每一个水平指定一种颜色。
colfill <- c(2:(1+length(levels(cyl.f))))
legend(locator(1), levels(cyl.f), fill=colfill)

detach(mtcars)
density_compare_plot.png

箱线图

箱线图同样是一种用来可视化分布和组间差异的绝佳图形手段(非常常用)。它通过绘制连续变量的五数总括——最小值、下四分位数、中位数、上四分位数以及最大值来描述连续型变量的分布。

箱线图能够显示出可能为离群点的观测(范围正负1.5*IQR以外的值,IQR表示四分位距,上四分位数与下四分位数之间的差值)。

例如:

boxplot(mtcars$mpg, main="Box Plot", ylab="Miles per Gallon")
box_plot.png

默认情况下,两条须的延伸极限不会超过盒型各端加1.5倍四分位距的范围,超过的都会用点表示。执行boxplot.stats(mtcars)即可输出构建图形的统计量。

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

使用格式:

boxplot(formula, data=dataframe)

第一个参数是公式,第二个是数据框或者列表。添加参数varwidth=TRUE将使箱线图的宽度与其样本大小的平方跟成正比。参数horizontal=TRUE可以反转坐标轴。

# 研究不同的发动机缸数对每加仑汽油行驶的英里数的影响
boxplot(mpg ~ cyl, data=mtcars,
        main="Car Mileage Data",
        xlab="Number of Cylinders",
        ylab="Miles Per Gallon")
car_mileage_data_plot.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")
car_mil_data_plot.png

交叉因子箱线图

为多个分组因子绘制箱线图。

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=T,
        col=c("gold", "darkgreen"),
        main="MPG Distribution by Auto Type",
        xlab="Auto Type", ylab="Miles Per Gallon")

mpg_dis_plot.png

点图

点图提供了一种在简单水平刻度上绘制大量有标签值的方法。你可以使用dotchart()函数创建点图,格式为:

dotchart(x, labels=)

其中x是一个数值向量,而labels则是由每个点的标签组成的向量。可以通过添加参数groups来选定一个因子,用以指定x中元素的分组方式。还可以用gcolor控制不同组标签的颜色,cex可以控制标签的大小。下面是一个示例:

dotchart(mtcars$mpg, labels=row.names(mtcars), cex=.7,
         main="Gas Mileage for Car Models",
         xlab="Miles Per Gallon")
dotchart_example.png

分组、排序、着色后的点图

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")

dotchart_example2.png

还有许多关于点图的变种。

本文参考

本文参考R in Action第二版记录,请注意原作版权。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,311评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,339评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,671评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,252评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,253评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,031评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,340评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,973评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,466评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,937评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,039评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,701评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,254评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,259评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,497评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,786评论 2 345

推荐阅读更多精彩内容