R语言入门系列之二

2022-05-05 11:16:13 浏览数 (1)

2数据管理与可视化

2.1数据预处理

在进行正式的数据分析之前,通常要对数据进行处理。而读取数据仅仅是最简单的,之后还要进行数据的筛选、排序、转换等。数据框是最方便的数据存储、管理对象。R有很多内置的示例数据集包括向量、矩阵数据框等,可以使用data()进行查看,接下来我们以R内置数据mtcars(32辆汽车在11个指标上的数据)为例进行分析,如下所示:

⑴内容添加与修改

①添加修改新变量

函数transform()可以在数据框中创建新变量,并使用其他变量进行赋值,如下所示:

代码语言:javascript复制
mydata=transform(mtcars, 
               sums=gear carb,
               means=(disp hp)/2)

运行结果如下:

within()函数可以在数据框内部进行操作,下面我们添加一新的类别变量:

代码语言:javascript复制
mydata=within(mydata, {
            size=NA #创建变量
            size[sums<6]="low"
            size[sums>=6 & sums<=8]="mid"
            size[sums>8]="high"
            size[sums==13]=NA
})

结果如下所示:

如果要修改数据框中已有的数据和变量名,可以使用fix()函数,该函数可以调用文本编辑器然后使用键盘来对数据框进行修改,如下所示:

使用names()函数可以调用或重新赋值变量名,如下所示:

②数据融合与删除

横向合并两个数据框,需要使用merge()函数,这时候会自动识别行名字并一一对应。如果仅仅是合并数据(不关心行、列的对应情况或者确定行、列正好对应),可以使用函数cbind()和函数rbind()来横向、纵向合并数据框或者矩阵、向量。

⑵特殊值

①缺失值

在实际研究中,缺失值是难以避免的(不能将缺失值NA当做0来对待),可以使用函数is.na()来判断是否存在缺失值,该函数可以作用于向量、矩阵、数据框等对象,返回值为对应的逻辑值,如下所示:

缺失值是无法进行比较运算的,很多函数都有参数na.rm选项来移除缺失值,如下所示:

可以使用函数na.omit()来移除变量中缺失值或矩阵、数据框含有缺失值的行,如下所示:

②日期值

在R中,日期往往以数值形式存储,日期值可以运算比较,但是在读取数据时往往读取为字符串格式,as.Date()函数可以将字符型日期转换为数值型进行储存,如下所示:

可以看到在R中日期值是以yyyy-mm-dd形式储存。在这里R可以识别yyyy-mm-ddyyyy/mm/dd格式的日期数据。

函数difftime()可以用来计算时间间隔,还可以自定义显示单位(周、天、时、分、秒),如下所示:

函数Sys.Date()可以返回当前日期,如下所示:

⑶数据标准化

在数据分析之前,我们往往要根据分析方法的需要对数据进行各种预处理,也即数据标准化。数据标准化的目的是使数据总体的参数符合某种要求(具体可参见1.4.3概率统计)。

简单数据转换也即对整体数据进行简单运算,数据转换的目的主要有三个,一是改变数据结构,例如非线性通过平方根、对数转换为线性;二是改变数据范围,便于比较和作图分析,例如数据变化特别大的可以进行对数转换来缩小属性范围;三是改变数据分布,使得样本偏离标准分布太远的更加接近标准分布(例如正态分布)。常见的数据转换有以下几种:

对数转换:将数据(样本观察值)取自然对数(或者其他数为底的对数),可以使用log()函数来实现(log1p()可以将数据加1后取自然对数)。若是数据中有0或负值,可以全部数据加上一个数转换为正数。一般来说自然对数转换可以使0~1范围内的数据范围变大,可以使>1范围内数据范围变紧凑。

平方根转换:将数据全部取平方根,可以使用sqrt(x)或者x^0.5来实现。类似的还有立方根转换、四次方根转换,偶数次方根要求数据非负。如果数据结构为二次关系,平方根转换后平方根转换可以使数据范围变小。

倒数转换:将数据全部取倒数,也即1/x,倒数转换使0~1范围内的数据范围变大,使>1范围内数据范围变紧凑,而且转换后数据为倒序。

数据转换仅仅是对数据中每个观察值的独立处理,而标准化则涉及到数值之间的处理。下面我们以生态学常用的vegan包中的decostand()函数为例,分析不同标准化方法的差别,此函数使用方法如下:

decostand(x, method, MARGIN, range.global, logbase=2, na.rm=FALSE, ...)

其中x为向量或矩阵,method为标准化方法,MARGIN=1按行处理,MARGIN=2按列处理:

①method="pa",将数据转换为有-无(1-0)类型,若分析不加权的情况群结构下可以使用;

②method="max",最大值标准化,将数据除以该行或者列的最大值(defaultMARGIN=2)。若数据非负,最大值标准化后数据全部位于0到1之间。

③method="total",总和标准化,将数据除以该行或者列的总和,也即求相对丰度(defaultMARGIN=1),总和标准化后数据全部位于0到1之间。

④method="range",Min-max标准化,将数据减去该行或者列的最小值,并比上最大值与最小值之差(defaultMARGIN=2),Min-max标准化后的数据全部位于0到1之间。

⑤method="normalize",模标准化,将数据除以每行或者每列的平方和的平方根(defaultMARGIN=1),模标准化后每行、列的平方和为1(向量的模为1),也即在笛卡尔坐标系中到原点的欧氏距离为1,样品分布在一个圆弧上,彼此之间的距离为弦长,因此也称为弦转化。在基于欧氏距离的PCA、RDA中分析群落数据可以将每个样方弦转化可以弥补欧氏距离的缺陷。弦转化后的数据使用欧氏距离函数计算将得到弦距离矩阵

⑥method="hellinger",hellinger转化,就是总和标准化数据的平方根(defaultMARGIN=1),hellinger转化后的数据使用欧氏距离函数计算将得到hellinger距离矩阵

⑦method="chi.square",卡方转化,在默认(defaultMARGIN=1)的情况下是数据除以行的和再除以列的和的平方根,卡方转化后的数据使用欧氏距离函数计算将得到卡方距离矩阵

⑧Wisconsin转化,这个是使用伴随的函数wisconsin(),将数据除以该列最大值再除以该行总和,是最大值标准化和总和标准化的结合。

⑨method="standardize",z-score标准化,最常用的标准化方法之一,将数据减去均值比上标准差(defaultMARGIN=2),z-score标准化后数据均值为0,方差为1,服从正态总体的数据标准化后服从标准正态分布。z-score标准化可以去除不同环境因子量纲的影响。

一般情况下,上面方法中默认MARGIN=1是默认对样品进行处理,默认MARGIN=2是默认对物种或者环境变量进行处理。

为了比较不同标准化方法对群落数据的影响,我们使用只有两个物种的虚拟群落进行处理,然后在笛卡尔坐标系进行展示(彼此之间是欧氏距离):

代码语言:javascript复制
#假设虚拟数据:2个物种在5个样方的分布
spe1=c(0.1,0.2,0.3,0.4,0.5)
spe2=c(0.6,0.7,0.8,0.9,1)
ab=cbind(spe1,spe2)
rownames(ab)=LETTERS[1:5]
#各种标准化
ab1=decostand(ab, MARGIN=1, "total")
ab2=decostand(ab, MARGIN=1, "normalize")
ab3=decostand(ab, MARGIN=1, "hellinger")
ab4=decostand(ab, MARGIN=1, "chi.square")
ab5=wisconsin(ab)
#作图观察不同标准化方法距离差异
par(mfrow=c(2,3))
plot(ab[,1], ab[,2], xlim=0:1, ylim=0:1, main="Rawdata")
text(ab[,1], ab[,2]-0.05, labels=rownames(ab), cex=1.2)
plot(ab1[,1], ab1[,2], xlim=0:1, ylim=0:1,main="Total")
text(ab1[,1], ab1[,2]-0.05, labels=rownames(ab), cex=1.2)
plot(ab2[,1], ab2[,2], xlim=0:1, ylim=0:1,main="Normalize")
text(ab2[,1], ab2[,2]-0.05, labels=rownames(ab), cex=1.2)
plot(ab3[,1], ab3[,2], xlim=0:1, ylim=0:1,main="Hellinger")
text(ab3[,1], ab3[,2]-0.05, labels=rownames(ab), cex=1.2)
plot(ab4[,1], ab4[,2], xlim=0:1, ylim=0:1,main="Chi.square")
text(ab4[,1], ab4[,2]-0.05, labels=rownames(ab), cex=1.2)
plot(ab5[,1], ab5[,2], xlim=0:1, ylim=0:1,main="Wisconsin")
text(ab5[,1], ab5[,2]-0.05, labels=rownames(ab), cex=1.2)

结果如下所示:

在没有处理的情况下,群落之间的欧氏距离相等,然而在生态学方面我们不这么看,因为B中物种1的数量是A的两倍,其群落差异显然比D、E更大,五种处理方法标准化数据后的结果都比较好的证实了上面的猜想,尤其是最后两种。然而在微生物生态中,我们倾向于认为微生物群落是一个整体,不同样品之间物种的相对丰度是有可比较的实际意义的,因此最常用的就是总和标准化(当然在不涉及丰度比较的聚类和排序分析中各种标准化方法都可以尝试,在传统群落研究里,虽然经常使用中心化等方法,但是需要使用盖度等对不同物种进行加权,因此直接进行总和标准化从某种意义上是使用相对丰度进行加权)。

对于物理、化学变量而言,则完全不同,因为环境变量的值具有绝对性,例如温度1-2℃和21-22℃其差异是一样的。环境变量由于量纲不同,在计算距离矩阵(欧氏距离)、根据特征根提取的主成分分析、比较系数的回归分析之前,均需要进行z-score标准化

2.2基础绘图

R是一个非常强大的数据可视化平台,使用R内置的作图函数可以轻松的构建各种类型的图形,此外还有各种作图包来使得图形更加“惊艳”。

R最常使用的作图函数为plot(),下面通过一个简单的例子来介绍R中图形构建方法:

attach(mtcars) #加载R内置示例数据(这是一个数据框,可自己查看)

plot(wt, mpg)

abline(lm(mpg~wt)) #绘制参考线

title("A Example of R Plot") #添加标题

作图结果如下所示:

⑴plot参数

plot()函数可根据两个数值变量数据绘制图形,并通过各种参数来美化图形,其使用方法及默认参数值如下所示:

plot(x = NULL, y = NULL, type = "p", xlim = NULL, ylim= NULL, log = "", main = NULL, sub = NULL, xlab = NULL, ylab = NULL,ann = par("ann"), axes = TRUE, frame.plot = axes, panel.first = NULL,panel.last = NULL, asp = NA, ...)

参数含义总结如下:

①作图类型type,如下所示:

②符号和线条

pch:指定绘制点所使用的符号,取值范围[0,24],如下所示:

cex:指定符号的大小。cex是一个数值,表示pch的倍数,默认是1.5倍

lty:指定线条类型。lty=1代表实线,2至6都是各种类型虚线

lwd:指定线条宽度,默认值为lwd=1,可以适当修改1.5倍、2倍等

③内容

main:字符串设置图片标题,main="Figurename",也可以使用函数title(),格式为title("MainTitle", sub="sub title", cex.main=2, font.main=4, col.main="blue",cex.sub=0.75, font.sub=3, col.sub="red"),也可以直接把title里面的参数直接放在plot()里面

xlab:字符串设置x轴标签

ylab:字符串设置x轴标签

④大小样式

cex.axis:坐标轴刻度文字的缩放倍数

cex.lab:坐标轴标签(名称)的缩放倍数

cex.main:标题的缩放倍数

cex.sub:副标题的缩放倍数

font:整数,用于指定坐标轴刻度字体样式;1常规、2粗体、3斜体、4粗斜体

las:整数,用于指定图形内部文字字体样式;具体同font

font.axis:坐标轴刻度文字的字体样式

font.lab:坐标轴标签(名称)的字体样式

font.main:标题的字体样式

font.sub:副标题的字体样式

family:设置字体,需要配合windowsFonts()函数使用,首先查看已经安装的字体:

然后通过family="serif"等来设置字体。

⑤颜色

col:绘图颜色。某些函数(如lines、pie)可以接受一个含有颜色值的向量,并自动循环使用。例如:col=c("red","blue")需要绘制三条线,那么三条颜色分别为red、blue、red

col.axis:坐标轴刻度文字的颜色,不是坐标轴的颜色

col.lab:坐标轴标签(名称)的颜色

col.main:标题的颜色

col.sub:副标题的颜色

fg:图形的前景色

bg:图形的背景色

⑥坐标轴

plot参数

axes=FALSE:将禁用全部坐标轴,框架和刻度全部没有了

xaxt="n"/yaxt="n":禁用x/y轴的刻度线

xlim:xlim=c(a,b)将x轴刻度范围限定在a到b

ylim:ylim=c(a,b)将y轴刻度范围限定在a到b

xaxs:控制x轴显示范围,默认为“r”,也即刻度范围扩大4%,设置为“i”则使用原始范围

yaxs:控制y轴显示范围,具体同上

也可以通过axis函数自定义axis(……)

side:一个整数。表示在图形的哪边绘制坐标轴(1=下,2=左,3=上,4=右)

at:一个数值向量,表示需要绘制刻度线的位置

labels:一个字符型向量(也可以是数值型),表示刻度线旁边的文字标签(刻度值),如果整个不写,则直接使用at的值

col:线条和刻度的颜色

lty:线条类型

las:因子坐标轴的标签的字体平行(=0)或者垂直(=2)坐标轴

tck:刻度线的长度(默认值-0.01,负值表示刻度在图形外,正值表示刻度在图形内侧)

log:log="x"或者log="y"或者log="xy",控制将坐标轴按照对数刻度绘制

⑦辅助函数

text():添加文本内容

legend():添加图例,legend(x= NULL, y = NULL, legend,fill = NULL, col = par("col"), border = "black", lty, lwd,pch, angle = 45, density = NULL, bty = "o", bg =par("bg")...)其中x、y为位置,legend为图例内容(字符串向量),fill用特定的颜色进行填充,border填充色的边框,lyt、pch、col图例的样式颜色(与图片对应),bty是否画图例框bty= "n"则不画出

abline():abline(h=yvalues,v=xvalues)或者abline(a, b),例如abline(h= c(1, 5))则在y=1和5处各有一条水平线,abline(v= c(1, 5))则在x=1和5处各有一条垂直线,abline(a,b)则绘制一条截距为a、斜率为b的斜线

points():在以由图形绘制点图

lines():在已有图形绘制线图

plot.new():绘制新的图形,如若不设置参数,绘制一个新的空白图形

segments():根据起止点坐标,在已有图形添加直线,例如segments(x0=2.5,y0=15.5, x1=2.5, y1=16.0)

⑵图片设置

par()函数是R中一个很重要的图片设置函数,而且是一个全局控制函数,其常用参数总结如下:

mar:数值向量控制绘图边界,例如mar=c(a,b, c, d)则a、b、c、d分别为图形下、左、上、右边界宽度,单位为英分,另有类似参数mai单位为英寸。

pin:数值向量控制图形尺寸,例如pin=c(a,b) 则a、b分别为图形的宽和高,单位为英寸

mfrow:数值向量控制在一页绘制的图片数目以及排列方式,例如设置par(mfrow=c(3,2))则表示同一页有三行两列共六个图,而且次序为按行填放。类似地,par(mfcol=c(3,2))规定相同的窗格结构,但是次序为按列填放,即先填满第一列的三个再填第二列

mfg:数值向量跳格方式一页多图,例如par(mfg=c(2,2,3,2))表示在三行两列的多图环境中直接跳到第二行第二列位置,mfg参数的后两个表示多图环境的行、列数,前两个表示要跳到的位置

此外,par()里也可以设置坐标轴大小字体样式cex、font等。

layout()函数是一个很好用的图形安排函数,不仅可以通过矩阵来设置作图顺序,还可以设置每幅图宽与高的比例,例如layout(matrix(c(1,2),1, 2), widths=c(2,1), heights=c(1,1))设置作图区域为1行两列共两幅图,图片宽之比2:1,高之比1:1。

⑶其他图形

①直方图

对于单一变量,我们可以采用hist()绘制直方图来展示在不同范围(字段)内数据分布,如下所示:

代码语言:javascript复制
attach(mtcars)
hist(mpg, nclass=10)

直方图将随机变量数值范围分成一定份数(可以通过breaks参数来设置),然后统计随机变量在每个范围内的数量或者比例,从而展示数据结构信息。

②箱型图

对于双变量其中一个为因子型变量或者分组变量,可以采用boxplot()箱型图来展示不同小组变量数据分布,如下所示:

代码语言:javascript复制
attach(mtcars)
boxplot(mpg~cyl, xlab="Cyl", ylab="Mpg")

箱型图中箱子的上下界分别为25%值和75%值(也即第一四分位数和第三四分位数),中间粗横线为中位数,触须伸出箱子的最大长度可以通过range参数来设置,默认为1.5倍箱子高度(四分位数间距),设置add=T可以讲箱形图绘制在当前图像上。其他图形例如柱状图bar()、扇形图pie()不再赘述。

2.3Ggplot2绘图

ggplot2(http://ggplot2.tidyverse.org/reference/)是专门用来绘制数据图形的R软件包,与其他R语言包相比,其语法相对独特,是基于图形语法(grammarof graphics)来进行绘图的工具。

⑴图形语法

ggplot2将图层作为主要考察对象,绘图的过程就是从统计数据几何对象(geometric object,geom)的图形属性(aestheticattributes,aes)的一个映射(mapping)。此外,数据中还可能包含数据的统计变换(statistical transformation,stats),最后绘制在某个特定的坐标系(coordinatesystem,coord)中,而分面(facet)则可以将绘图区域分为若干个子区域来绘图。

数据(data):用于可视化的统计数据,一般为一个数据框

几何对象(geom):点、线、多边形等具体图形

图形属性(aes):颜色、形状、大小等

统计变换(stats):对数据的某种汇总以便于展示

标度(scale):将数据的取值映射到图形空间

ggplot2中两个主要的作图函数为qplot()和ggplot()。qplot()更简单一些但是参数较少,下面通过一个简单的例子来介绍ggplot2图形构建方法:

代码语言:javascript复制
attach(mtcars) #加载R内置示例数据
library(ggplot2)
ggplot(mtcars, mapping=aes(x=wt, y=mpg))  
   geom_point(color="darkred", size=2)

作图结果如下所示:

我们继续根据因子cyl对数据点进行分组并添加趋势线:

代码语言:javascript复制
ggplot(mtcars, mapping=aes(x=wt, y=mpg))  
  geom_point(size=2,mapping=aes(colour=factor(cyl)))  
  geom_smooth(method=lm,se=FALSE, fullrange=TRUE)

其中geom_smooth()函数可以在图层上添加平滑的趋势线,这里选择了回归的方法,则显示回归曲线,作图结果如下所示:

可以看出,ggplot通过mapping=aes()来映射图形属性,通过“ ”来添加图层,使用数据框作为输入数据。ggplot2不能识别矩阵,所有分组信息也必须转换为因子变量组成数据框。由于数据框存储的数据量要远大于矩阵,因此ggplot2可以做出信息含量更加丰富的图形。

⑵直方图

在ggplot2中,geom_histogram()可以在图层上添加直方图,stat_density()可以在图层上添加密度曲线,我们使用ggplot内置的示例数据mpg做直方图,如下所示:

代码语言:javascript复制
ggplot(mpg, aes(x=hwy))   
geom_histogram(position='identity', alpha=0.5,binwidth=1, aes(y=..density.., fill=factor(year)))  
stat_density(geom='line', position='identity', aes(colour=factor(year)))

其中position='identity'则两部分数据图形重叠,为'dodge'则并列展示,为'stack'则堆叠展示;默认为y轴是频数,y=..density..则为数据百分比率;binwidth为每个范围矩形图形宽度。geom='line'则做线图,为'point'这时就等于geom_point()函数。在这些作图函数中也可以添加size、lty、pch等参数,其值的含义与R基础作图函数plot()相同。作图结果如下所示:

⑶柱状图

使用geom_bar函数可以做柱状图,示例如下:

代码语言:javascript复制
library(ggplot2)
y=c(1.0,1.8,2.8,3.8,3.4,2.7,1.8,-0.3,-2.8,2.5, 1.8)
x=2001:2011
data=data.frame(x,y)
p=ggplot(data,aes(x, y, fill=y))
p geom_bar(stat="identity")  scale_fill_gradient2(low="red4", high="green4",mid="yellow")  
  geom_abline(intercept=0,slope=0, size=1, colour='gray')   
  geom_text(aes(label=y),hjust=0.5, vjust=-0.5)  
 scale_y_continuous(limits=c(-3.8, 4.2))  
  labs(x='Year', y='GDPgrowth rate%')

其中scale_y_continuous为设置y轴范围,geom_abline()添加标准线并在其两边绘图,geom_text()添加文本内容,作图结果如下:

0 人点赞