重点内容
探索R中的数据结构
输入数据
导入数据
标注数据
老师上课讲了,快速过一下
- R中有许多用于存储数据的结构,包括标量、向量、数组、数据框和列表
- 实例标识符称为rownames(行名)
- 类别型(包括名义型和有序型)变量称为因子(factors)
- 对象(object):指可以赋值给变量的任何事物,包括常量、数据结构、函数, 甚至图形。
- 对象都拥有某种模式,描述了此对象是如何存储的,以及某个类,像print这样的 泛型函数表明如何处理此对象。
- 数据框(data frame)是R 中用于存储数据的一种结构:列表示变量,行表示观测。在同一个数据框中可以存储不同类型 (如数值型、字符型)的变量。
- 因子(factor)是名义型变量或有序型变量。
2.2.1向量
- c():创建向量
- 通过在方括号中给定元素所处位置的数值,我们可以访问向量中的元素。
- :用于生成数值序列
a <- c(1, 2, 5, 3, 6, -2, 4)
b <- c("one", "two", "three")
c <- c(TRUE, TRUE, TRUE, FALSE, TRUE, FALSE)
# 这里,a是数值型向量,b是字符型向量,而c是逻辑型向量。
> a <- c("k", "j", "h", "a", "c", "m")
> a[3]
[1] "h"
> a[c(1, 3, 5)]
[1] "k" "h" "c"
> a[2:6]
[1] "j" "h" "a" "c" "m"
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包含了可选 的、以字符型向量表示的行名和列名。
- 选项byrow则表明矩阵应当按行填充(byrow=TRUE) 还是按列填充(byrow=FALSE),默认情况下按列填充。
创建矩阵
> y <- matrix(1:20, nrow=5, ncol=4)
> y
[,1] [,2] [,3] [,4]
[1,] 1 6 11 16
[2,] 2 7 12 17
[3,] 3 8 13 18
[4,] 4 9 14 19
[5,] 5 10 15 20
> cells <- c(1,26,24,68)
> rnames <- c("R1", "R2")
> cnames <- c("C1", "C2")
> mymatrix <- matrix(cells, nrow=2, ncol=2, byrow=TRUE,
dimnames=list(rnames, cnames))
> mymatrix
C1 C2
R1 1 26
R2 24 68
> mymatrix <- matrix(cells, nrow=2, ncol=2, byrow=FALSE,
dimnames=list(rnames, cnames))
> mymatrix
C1 C2
R1 1 24
R2 26 68
矩阵下标的使用
> x <- matrix(1:10, nrow=2)
> x
[,1] [,2] [,3] [,4] [,5]
[1,] 1 3 5 7 9
[2,] 2 4 6 8 10
> x[2,] # 第2行
[1] 2 4 6 8 10
> x[,2] # 第2列
[1] 3 4
> x[1,4] # 第一行第四列的数据
[1] 7
> x[1, c(4,5)] # 第一行,第四五列的数据
[1] 7 9
2.2.3数组
数组(array)与矩阵类似,但是维度可以大于2。数组可通过array函数创建,形式如下:
myarray <- array(vector, dimensions, dimnames)
- 其中vector包含了数组中的数据,
- dimensions是一个数值型向量,给出了各个维度下标的最大值,
- 而dimnames是可选的、各维度名称标签的列表。
> dim1 <- c("A1", "A2")
> dim2 <- c("B1", "B2", "B3")
> dim3 <- c("C1", "C2", "C3", "C4")
> z <- array(1:24, c(2, 3, 4), dimnames=list(dim1, dim2, dim3))
> z
, , C1
B1 B2 B3
A1 1 3 5
A2 2 4 6
, , C2
B1 B2 B3
A1 7 9 11
A2 8 10 12
, , C3
B1 B2 B3
A1 13 15 17
A2 14 16 18
, , C4
B1 B2 B3
A1 19 21 23
A2 20 22 24
2.2.4 数据框
- data.frame():创建
mydata <- data.frame(col1, col2, col3,...)
其中的列向量col1、col2、col3等可为任何类型(如字符型、数值型或逻辑型)。每一列的名 称可由函数names指定。
创建数据框&获取数据框中元素:
> patientID <- c(1, 2, 3, 4)
> age <- c(25, 34, 28, 52)
> diabetes <- c("Type1", "Type2", "Type1", "Type1")
> status <- c("Poor", "Improved", "Excellent", "Poor")
> patientdata <- data.frame(patientID, age, diabetes, status)
> patientdata
patientID age diabetes status
1 1 25 Type1 Poor
2 2 34 Type2 Improved
3 3 28 Type1 Excellent
4 4 52 Type1 Poor
> patientdata[1:2]
> patientdata[c("diabetes","status")] #直接通过向量c()的方法摘取列也可以
> patientdata$age #表示patientdata数据框中的变量age
- $:被用来选取一个给定数据框中的某个特定变量
- 如果你想生成糖尿病类型变量diabetes和病情变量status的列联表:
table(patientdata$diabetes, patientdata$status)
#注意,table生成的是列联表,dataframe是数据框,区别如下
patientdata.diabetes patientdata.status
1 Type1 poor
2 Type2 improved
3 Type1 excellent
4 Type1 poor
table(patientdata$diabetes,patientdata$status)
excellent improved poor
Type1 1 0 2
Type2 0 1 0
简化代码
在每个变量名前都键入一次patientdata$可能会让人生厌,所以不妨走一些捷径。
可以联 合使用函数attach()和detach()或单独使用函数with()来简化代码
attach()、detach()和with():函数attach()和detach()最好在你分析一个单独的 数据框,并且不太可能有多个同名对象时使用。任何情况下,都要当心那些告知某个对象已被屏 蔽(masked)的警告
函数attach()可将数据框添加到R的搜索路径中。R在遇到一个变量名以后,将检查搜索路 径中的数据框。
以第1章中的mtcars数据框为例,可以使用以下代码获取每加仑行驶英里数(mpg) 变量的描述性统计量,并分别绘制此变量与发动机排量(disp)和车身重量(wt)的散点图:
summary(mtcars$mpg)
plot(mtcars$mpg, mtcars$disp)
plot(mtcars$mpg, mtcars$wt)
以上代码也可写成:
attach(mtcars)
summary(mpg)
plot(mpg, disp)
plot(mpg, wt)
detach(mtcars)
函数detach()将数据框从搜索路径中移除。值得注意的是,detach()并不会对数据框本身 做任何处理。这句是可以省略的,但其实它应当被例行地放入代码中,因为这是一个好的编程习 惯。
with():赋值仅在此函数的括号内生效。
上例可以改为
with(mtcars, {
print(summary(mpg))
plot(mpg, disp)
plot(mpg, wt)
})
花括号{}之间的语句都针对数据框mtcars执行,这样就无需担心名称冲突 了。如果仅有一条语句(例如summary(mpg)),那么花括号{}可以省略。
- 赋值仅在此函数的括号内生效。即,括号外想要显示赋值内容,无法显示
- 改良:如果你需要创建在with()结构以外存在的对象,使用特殊赋值符<<-替代标准赋值符(<-) 即可,它可将对象保存到with()之外的全局环境中。
> with(mtcars, {
stats <- summary(mpg)
stats
})
Min. 1st Qu. Median Mean 3rd Qu. Max.
10.40 15.43 19.20 20.09 22.80 33.90
> stats
Error: object 'stats' not found
实例标识符
在病例数据中,病人编号(patientID)用于区分数据集中不同的个体。在R中,实例标识 符(case identifier)可通过数据框操作函数中的rowname选项指定。
patientdata <- data.frame(patientID, age, diabetes, status, row.names=patientID)
将patientID指定为R中标记各类打印输出和图形中实例名称所用的变量
2.2.5 因子:它决定了数据的分析方式以及如何进行视觉呈现
变量可归结为名义型、有序型或连续型变量。
- 名义型变量是没有顺序之分的类别 变量。
- 有序型变量表示一种顺序关系,而非数量 关系。
- 连续型变量可以呈现为某个范围内的任意值,并同时表示了顺序和数量。
- 因子(factor)=类别(名义型)+有序类别(有序型)。
函数factor()以一个整数向量的形式存储类别值,整数的取值范围是[1...k](其中k是名义 型变量中唯一值的个数),同时一个由字符串(原始值)组成的内部向量将映射到这些整数上。
diabetes <- c("Type1", "Type2", "Type1", "Type1")
diabetes <- factor(diabetes)
将此向量存储为(1, 2, 1, 1),并在内部将其关联为 1=Type1和2=Type2(具体赋值根据字母顺序而定)。
针对向量diabetes进行的任何分析都会将其 作为名义型变量对待,并自动选择适合这一测量尺度①的统计方法
要表示有序型变量,需要为函数factor()指定参数ordered=TRUE。给定向量:
status <- c("Poor", "Improved", "Excellent", "Poor")
status <- factor(status, ordered=TRUE)
会将向量编码为(3, 2, 1, 3),并在内部 将这些值关联为1=Excellent、2=Improved以及3=Poor。
- 字符型
对于字符型向量,因子的水平默认依字母顺序创建。这对于因子status是有意义的,因为 “Excellent”“Improved”“Poor”的排序方式恰好与逻辑顺序相一致。如果“Poor”被编码为 “Ailing”,会有问题,因为顺序将为“Ailing”“Excellent”“Improved”。
如果理想中的顺序是“Poor” “Improved”“Excellent”,则会出现类似的问题。按默认的字母顺序排序的因子很少能够让人满意。
你可以通过指定levels选项来覆盖默认排序。
status <- factor(status, order=TRUE, levels=c("Poor", "Improved", "Excellent"))
- 数值型变量
可以用levels和labels参数来编码成因子。如果男性被编码成1,女性被编码 成2,则以下语句:
sex <- factor(sex, levels=c(1, 2), labels=c("Male", "Female"))
小知识点
- str(patientdata):展示对象结构
- summary(patientdata):展示统计概要
2.2.6列表:列表就是一些对象(或成分, component)的有序集合。
mylist <- list(object1, object2, ...)
创建一个列表
> g <- "My First List"
> h <- c(25, 26, 18, 39)
> j <- matrix(1:10, nrow=5)
> k <- c("one", "two", "three")
> mylist <- list(title=g, ages=h, j, k)
> mylist
$title
[1] "My First List"
$ages
[1] 25 26 18 39
[[3]]
[,1] [,2]
[1,] 1 6
[2,] 2 7
[3,] 3 8
[4,] 4 9
[5,] 5 10
[[4]]
[1] "one" "two" "three"
> mylist[[2]] # 输出第二个成分
[1] 25 26 18 39
> mylist[["ages"]]
[[1] 25 26 18 39
在双重方括号中指明代表某个成分的数字或名称来访问列表中的元素。
一些小知识点
对象名称中的句点(.)没有特殊意义,但美元符号($)却有着和其他语言中的句点 类似的含义,即指定一个数据框或列表中的某些部分。例如,A$x是指数据框A中的变 量x。
❑R不提供多行注释或块注释功能。你必须以#作为多行注释每行的开始。出于调试目的, 你也可以把想让解释器忽略的代码放到语句if(FALSE){... }中。将FALSE改为TRUE 即允许这块代码执行。
❑将一个值赋给某个向量、矩阵、数组或列表中一个不存在的元素时,R将自动扩展这个 数据结构以容纳新值。举例来说,考虑以下代码: > x x[7] 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 <- data.frame(age=numeric(0),
gender=character(0), weight=numeric(0))
mydata <- edit(mydata) # 编辑的结果需要赋值回对象本身
- read.table():
mydatatxt <- "
age gender weight
25 m 166
30 f 115
18 f 120
"
mydata <- read.table(header=TRUE, text=mydatatxt)
# 一个字符型变量被创建于存储原始数据,然后read.table()函数被用于处理字符串并返回数据框
2.3.2 从带分隔符的文本文件导入数据
mydataframe <- read.table(file, options)
举个例子
如何导入数据有很多有趣的要点。
变量名Social Studies被自动地根据R的习惯所重命名。
- 列StudentID现在是行名,不再有标签,也失去了前置的0。
- Jane的缺失的科学课成绩被正确地 识别为缺失值。
- 不得不在Dan的姓周围用引号包围住,从而能够避免Thornton和III之间的空格。 否则,R会在那一行读出七个值而不是六个值。我也在O’Leary左右用引号包围住了,负载R会把 单引号读取为分隔符(而这不是我想要的)。
- 最后,姓和名都被转化成为因子。
- 默认地,read.table()把字符变量转化为因子,这并不一定都是我们想要的情况。比如说, 很少情况下,我们才会把回答者的评论转化成为因子。你可用多种方法去掉这个行为。
- 加上选项 stringsAsFactors=FALSE对所有的字符变量都去掉这个行为。
- 此外,你可以用colClasses 选项去对每一列都指定一个类(比如说,逻辑型、数值型、字符型或因子型)
也可以是:
grades <- read.table("studentgrades.csv", header=TRUE,
row.names="StudentID", sep=",", colClasses=c("character",
"character", "character", "numeric", "numeric", "numeric"))
# 行名保留了前缀0,而且First和Last不再是因子。
# 此外,grades作为实数而不是整数来进行排序
# 原本的代码是:
grades <- read.table("studentgrades.csv",
header=TRUE, row.names="StudentID", sep=",")
小知识点
- 函数file()允许你访问文件、剪贴板和C级别的标准 输入。
- 函数gzfile()、bzfile()、xzfile()和unz()允许你读取压缩文件。
- 函数url()能够让你通过一个含有http://、ftp://或file://的完整URL访问网络上的文件,还 可以为HTTP和FTP连接指定代理。为了方便,(用双引号围住的)完整的URL也经常直接用来 代替文件名使用。
- 更多详情,参见help(file)。
2.3.3 导入Excel数据
- 法1:在Excel中将其导出为一个逗号分隔文件(csv),并使 用前文描述的方式将其导入R中。
- 法2:可以用xlsx包直接地导入Excel工作表。你也需要xlsxjars和rJava包,以及一个正常工作的Java 安装(http://java.com)。
- 可以处理的包:
- read.xlsx2():大型数据簿
- XLConnect、openxlsx
# 从位于C盘根目录的工作簿myworkbook.xlsx中导入了第一个工作表,并将其保存为一个数据框mydataframe
library(xlsx)
workbook <- "c:/myworkbook.xlsx"
mydataframe <- read.xlsx(workbook, 1)
2.3.5 网页抓取数据:用户从互联网上提取嵌入在网页中的信息,并将其保存 为R中的数据结构以做进一步的分析
- 一个网页上的文字可以使用函数readLines()来 下载到一个R的字符向量中,然后使用如grep()和gsub()一类的函数处理它
- 对于结构复杂的 网页,可以使用RCurl包和XML包来提取其中想要的信息。
查看CRAN Task View中的子版块Web Technologies and Services(CRAN Task View: Web Technologies and Services)来获得一个 全面的列表,此列表列出了能帮助你获取网上资源的各种R包
2.3.6 spss
2.3.8 stata
2.4 数据集的标注
2.4.1变量标签
names(patientdata)[2] <- "Age at hospitalization (in years)"
# 将age重命名为"Age at hospitalization (in years)"
2.4.2 值标签
函数factor()可为类别型变量创建值标签。
patientdata$gender <- factor(patientdata$gender,
levels = c(1,2),
labels = c("male", "female"))
# 这里levels代表变量的实际值,而labels表示包含了理想值标签的字符型向量。