感谢Robert I.Kabacoff 著作了这本书,同时感谢高涛、肖楠、陈钢编译此书。
最近在学习《R语言实战》,特将学习过程记录下来,供各位朋友参考,虽说是笔记,但是90%是书中内容,另外10%是自己偶尔冒出的一点点想法的记录和一些疑问,希望互相探讨。末尾有本书的代码清单下载地址,供各位下载,还是提倡按照书中内容把代码一个个敲出来。
第一章 R语言介绍
自定义启动环境以自动载入会频繁使用的包 ——
P14
问: 如何自定义启动环境?
常见错误类型
- 注意大小写
- 注意引号与括号是否漏了;
- 路径名称使用 “/” 或者 “\”;
- 是否使用未载入包的函数
第二章 创建数据集
按照个人要求的格式来创建含有研究信息的数据集是数据分析的第一步。这个任务包括以下两步:
- 选择一种数据结构来存储数据
- 将数据输入或导入到这个结构中
本章的第一部分(2.1~2.2节)叙述了R中用于存储数据的多种结构。
本章的第二部分(2.3节)涵盖了多种向R中导入数据的可行方法,通常,你只需要其中的一两种方法。
本章的第三部分(2.4节)将讨论数据集的标注问题,并在2.5节介绍一些处理数据集的使用函数。
2.1 数据集的概念
由数据构成的矩形数组,行表示观测,列表示变量。
不同行业对于数据集的行列叫法不同,统计学家称之为 观测 (observation)和 变量 (variable),
数据库分析师称之为 记录 (record)和 字段 (field),数据挖掘/机器学习学科的研究者则把他们叫
做示例(example)和属性(attribute)。
2.2数据结构
包括标量、向量、矩阵、数组、数据库和列表。
2.2.1 向量
用于存储数值型、字符型或逻辑型数据的一维数组。用函数c()可创建向量。
例如
a <- c(2,1,5,6,4)
b <- c("北京","上海",广州","深圳")
c <- c(TRUE,TRUE,FALSE,FALSE)
注意
标量是只含有一个元素的向量,例如f <- 2、g <- "中国"和h <- TRUE。它们用于保存常量。
访问向量中的指定元素可用方括号表示,如:a[c(2,4)],用于访问a中的第二个和第四个元素,即1和6。
2.2.2 矩阵
矩阵是一个二维数组,只是每个人元素都拥有相同的模式(数值型、字符型或逻辑型)用函数matrix来创建矩阵。
myymatrix <- matrix(vector,nrow=number_of_rows,ncol=number_of_columns,byrow=logical_value,dimnames=list(char_vector_rownames,char_vector_colnames))
其中vector包含了矩阵的元素,nrow和ncol用于指定行和列的维数,dimnames包含了可选的,以字符型向量表示的行名和列名,选项byrows则表明矩阵应当按行填充(byrow=TRUE)还是按列填充(byrow=FALSE),默认是按列填充。
提取矩阵中的元素时用[,],其中逗号前后分辨是,行数和列数。
如:
`x <- matrix(1:10,nrow=2) #创建一个1到10、两行的矩阵。
x #查看矩阵内容。
x[2,] #查看x中,第二行的元素,即2 4 6 8 10。
x[,2] #查看x中,第二列的元素,即3 4。
x[1,4] #查看x中,第一行,第四列的元素,即7。
x[1,c(4,5)] #查看x中,第一行,第四、五列的元素,即7 9。`
2.2.3 数组
与矩阵类似,但是维度可以大于2。可通过函数array来创建,形式如下:
myarry <- array(vector,dimensions,dimnames)
其中vector包含了数组中的数据,dimensions是一个数值型向量,给出了各个维度下标的最大值,而dimnames是可选的、各维度名称标签的列表。
问:
-
既然维度可以大于2,那么当维度为3、4的时候,是怎样的形式?
-
下标是什么意思?
2.2.4 数据框
在R中最常处理的数据结构,不同列可以包含不同模式(数值型、字符型等)的数据,同一列的数据模式必须相同。可通过函数data.frame()来创建,如:
mydata <- data.frame(col1,col2,col3,…)
其中的列向量col1,col2,col3,…可为任意类型,(如数值型、字符型或逻辑型)每一列的名称可由函数names指定。
使用$来提取数据狂中的特定元素,但是每次都输入数据框名,有点麻烦,用attach(),detach()和with()函数来简化代码。
1. attach(),detach()和with()函数
函数attach()可以将数据库添加到R的搜索路径中,函数detach()将数据框从搜索路径中移除,
和with()函数
当名称相同的对象不止一个时,attach()与detach()组合的方式,局限性就很明显。
当环境中已经有一个此名称的对象时,原始对象取得优先权。
使用with()的局限性在于,赋值仅在此函数的括号内生效,如果需要创建with()结构以外存在的对象,使用特殊赋值符<<- 替代标准赋值符(<-),它可以将对象保存到with()以外的全局环境中。
2. 实例标识符
在R中,可通过数据框操作函数中的rowname选项将对象指定为R中标记各类打印输出和图形中实例名称所用的变量。如:
patientdata <- data.frame(patientID,age,diabetes,status,row.names=patientID)
2.2.5 因子
变量分为名义型、有序型或连续型变量。
- 名义型变量是没有顺序的类别型变量。如病人患病类型(Type1、Type2)。
- 有序型变量表示一种顺序,而非数量关系的变量。如病情(很差、较好、痊愈)。
- 连续型变量可以呈现为某个范围内的任意值,并同时表示了顺序和数量。
其中的名义型变量和有序型变量都是因子,因子很重要,因为它决定了数据的分析方式以及如何进行视觉呈现。
函数factor()以一个整数向量的形式存储类别值,整数的取值范围是[1~k](其中k是名义型变量中唯一值得个数),同时一个由字符串(原始值)组成的内部向量将映射到这些整数上。要表示有序型变量需为函数factor()指定参数ordered()
这里对向量的编码使用的是字母顺序,可以通过指定levels选项来覆盖默认排序。
四分位数
将n个数值从小到大排列,分别在20%,50%,75%的位置
Q1的位置= (n+1) × 0.25
Q2的位置= (n+1) × 0.5
Q3的位置= (n+1) × 0.75
2.2.6 列表
是R中最为复杂的一张数据类型,是一些对象(或成分,component)的有序集合。用函数list()来创建。
mylist <- list(obecjt1,obecjt2,…)
其中的对象可以是目前为止讲到的任何结构。还可以为列表中的对象命名。
mykist <- list(name1 = obecjt,name2 = obecjt2,…)
两个原因让列表成为了R中的重要数据结构。
1. 列表允许以一种简单的方式组织和重新调用不想干的信息
2. 许多R函数的运行结果都是以列表的形式返回的
<div align = "center">R语言中的不寻常特性</div>
<div align = "right">P30</div>
-
对象名称中的句点(.)没有特殊意义。但美元符号($)却有着和其他语言中的句点相类似的含义,即指定一个对象中的某些部分。例如,A$x是指数据框A中的变量x。
-
R不提供多行注释或块注释功能,必须以#作为多行注释每行的开始。出于调试的目的,你也可以把想让解释器忽略的代码放到语句if(FALSE){……}中。将FALSE改为TRUE即允许这块代码执行。
-
将一个指赋给某个向量、矩阵、数组或列表中一个不存在的元素时,R将自动扩展这个数据结构以容纳新值。如:
x <- c(8,6,4)
x[7] <- 10
x
[1] 8 6 4 NA NA NA 10
通过赋值,向量x由三个元素扩展到了七个元素,
x <- x[1:3]
会重新将其缩减回三个元素。
- R中没有标量,标量以氮元素向量的形式出现。
- R中的下标不从0开始,而从1开始。在上述向量中,x[1]的值为8。
- 变量无法被声明。它们在首次被赋值时生成。
2.3 数据的输入
2.3.1 使用键盘输入数据
使用函数edit()会自动调用一个允许手动输入数据的文本编辑器。具体步骤如下:
- 创建一个空数据框(或矩阵),其中变量名和变量的模式需与理想中的最终数据集一致;
- 针对这个数据对象调用文本编辑器,输入你的数据,并将最终结果保存回此数据对象中。
mydata <- edit(mydata) 可以等价于 fix(mydata)
2.3.2 从带分隔符的文本文件中导入数据
使用read.tabe()函数语法如下:
mydataframe <- read.table(file,header=logical_value,sep="delimiter",row.names="name")
其中,file是一个带分隔符的ASCII文本文件,header是一个表明首行是否包含了变量名的逻辑值(TRUE或FALSE),sep用来指定分隔数据的分隔符,row.names是一个可选参数,用以指定一个或多个表示行表示符的变量。
默认情况下,字符型变量将转换为因子,如果不想这样,有很多种方法可以禁止这种转换行为。其中包括设置选项stringsAsFactors = FSLSE,另一种方法是使用选项colClasses为每一列指定一个类,如logical(逻辑型)、numeric(数值型)、character(字符型)、factor(因子)。
2.3.3 导入Excel数据
可以将Excel文件导出为一个逗号分隔文件(csv),并使用前文额方式导入R中。
在Windows系统中,可以用RODBC包来访问Excel文件。
下载安装好RODBC包之后,可用read.xlsx/xls(file,n)来读取数据,其中file表示文件的路径,需用"file"表示,n表示要导入的工作表序号。
书中使用了xlsx包,在下载此包之前,需做以下步骤:<p>
- 在JAVA官网下载JDK安装,并设置环境变量。(操作方式)
- 在R中下载rjava包,载入;
- 在R中下载xlsxjars包,载入;
- 在R中下载xlsx包,载入;
- 使用书中范例进行操作。
2.3.4 导入XML数据
2.3.5 从网页抓取数据
- 使用reanLines()下载网页
- 使用grep()和gsub()一类的函数进行处理
对于结构复杂的网页,使用RCurl包和XML包来提取想要的信息。在载入RCurl包之前需载入bitops包。
找到“Webscraping using readLines and RCurl”一文
2.3.6 导入SPSS数据
用foreign包的函数read.spss(),也可用Hmisc包的函数spss.get(),后者是对前者的一个封装,可自动设置后者的许多参数,让转换结果更加简单一致。Hmisc包需载入。
注意:在载入Hmisc包之前需要载入以下几个包。
-
lattice包<p>
install.packages("lattice")
library(lattice)
-
survival包<p>
install.packages("survival")
library(survival)
-
Formula包<p>
install.packages("Formula")
library(Formula)
-
ggplot2包<p>
install.packages("ggplot2")
library(ggplot2)
然后就可以用spss.get()函数来导入数据了,如:<p>
mydataframe <- spss.get("mydata.sav),use.value.labels = TRUE)
其中,mydata.sav是需要导入的spss文件,use.value.label = TRUE表示让函数将带有值标签的变量导入为R中水平对应相同的因子,mydataframe是导入后的R数据框。
2.3.7 导入SAS数据
使用foreign包的read.ssd()函数或者Hmisc包的sas.get()函数都可以,倘若使用的SAS是9.1或者更高版本,则这些函数无法正常使用。因为R尚未跟进SAS对文件结构的改动。可以使用以下两种方案:
- 在SAS中使用PROC EXPORT将SAS数据集保存为一个逗号分隔的文本文件,并使用2.3.2节中叙述的方法将导出的文件读取到R中,如:
SAS程序:<p>
proc exprot data = mydata
<p>
outfile = "mydata.csv
<p>
dbms = csv;
<p>
run;
<p>
R程序<p>
mydata <- read.table("mydata.csv",header = TRUE,sep = ",")
另外,一款名为Stat/Transfer的商业软件(在2.3.12节介绍)可以完好地将SAS数据集(包括任何一支的变量格式)保存WieR数据框。
2.3.8 导入Stata数据
在R中使用类似代码:
library(foreign)
mydataframe <- read.dta("mydata.dta")
其中,mydat.dta是Stata数据集,mydataframe是返回的R数据框。
2.3.9 导入netCDF数据
Unidata项目主导的开源软件库netCDF(network Common Data Form,网络通用数据格式)定义了一种机器无关的数据格式,可用于创建和分发面向数组的科学数据。netCDF格式通常用来存储地球物理数据。ncdf包和ncf4包为netCDF文件提供了高层的R接口。
问
- 什么叫做机器无关?
- 高层的R接口是什么意思?
- 这两个包与普通的R包有什么区别?
ncdf包为版本3或更早版本的netCDF库创建的数据文件提供了支持,在windows、Mac OS X和Liunx平台上均可使用。ncdf4包支持netCDF 4或更早的版本,在windows平台上不可用。
使用以下代码:
library(ncdf)
<p>
nc <- nc_open("mybetCDFfile")
<p>
myarray <- get.var.ncdf(nc,myvar)
<p>
在本例中,对于包含netCDF文件mybetCDFfile中的变量myvar,其所有数据都被读取并保存到了一个名为myarray的R数组中。
值得注意的是:ncdf和ncdf4包最近进行来了重大升级,使用方式可能与旧版本不同,另外这两个包中的函数名称也不同。请阅读在线文档以了解详情。
2.3.10 导入HDF5数据
hdf全称是Hierarchical Data Format,分层数据格式,用于管理超大型和结构几段复杂数据集的软件技术方案。在安装了HDF5库(1.2版或更高)之后,可以用hdf5包读取HDF5的数据。
2.3.11 访问数据库管理系统
在R中,通过两种方式来获取关系型数据框管理系统(DSMS),一部分是通过原生的数据框驱动来提供访问功能,另一部分是通过ODBC或JDBC来实现访问的。
1. ODBC接口
在R中使用ODBC包访问一个数据框,能连接到任意一种拥有ODBC驱动的数据库。步骤如下:
- 针对你的系统和数据框类型安装和配置合适的ODBC驱动。
- 在R中安装载入RODBC包。
RODBC包可以允许R和一个通过ODBC连接的SQL数据库之间进行双向通信。不仅可以读取数据还可以通过R修改数据库中的内容。
library(RODBC)
①<P>
myconn <- odbcConnect("mydsn",uid = "Rob",pwd = "aardvark")
②<p>
crimedat <- sqlFetch(myconn,Crime)
③<p>
pundat <- sqlQuery(myconn,"select * from Punishment")
④<p>
close(myconn)
⑤<p>
① 载入RODBC包
② 通过一个已注册的数据源名称(mydsn)和用户名(rob)以及密码(aardvark)打开了一个ODBC数据库连接。
③ 连接字符串被传递给sqlFetch,它将Crime表赋值到R数据框crimedat中。
④ 对Punishment表执行了SQL语句select并将结果保存到pundat中。
⑤ 关闭连接。
问:
- 关闭连接是否是必须的?
- 不关闭连接会怎样?
2. DBI相关包
DBI相关包为访问数据库提供了一个通用且一致的客户端接口。使用时请确保安装了针对你的系统和数据库的必要JDBC驱动。详细请参阅CRAN<p>
问:
- 两个接口有什么区别?
- 哪一种更便捷,或者更为普遍的使用?
2.3.12 通过Stat/Transfer导入数据
一款可在34种数据格式之间做转换的独立应用程序。此软件拥有Windows、Mac和Unix版本,支持前文叙述的各种统计软件的最新版本。也可以铜鼓ODBC访问如Oracle、Sybase、Informix和DB/2一类的数据库管理系统。
2.4 数据集的标注
为了是结果更易解读,通常会对数据集进行标注。通常这种标注包括为变量名添加描述性标签,以及为类别型变量中的编码添加值标签。
2.4.1 变量标签
将变量标签作为变量名,然后通过位置下标来访问这个变量。
names(patientdata)[2] <- "Age at hostipalizantion (in years)"
使用此串文中代码,再输入Age at hostipalizantion (in years)
会报错,这是为什么?
2.4.2 值标签
函数factor()可为类别型变量创建值标签 。在上例中,假设又一个名为gender的变量,其中1表示男性,2表示女性。可以使用以下代码。
patientdata$gender <- factor(patientdata$gender,levels = c(1,2),labels = c("male","female"))
这里的levels代表变量的实际值,而labels表示包含了理想值标签的字符型向量。
2.5 处理数据对象的实用函数
<p>
<p>
2.6 小结
<p>
<p>
<p>
网友评论