《R语言实战》学习笔记 -- 第二章 数据结构

数据类型

向量

  • 创建

向量(vector)是用于存储数值型、字符型或逻辑型数据的一维数组。执行组合功能的函数 c() 可用来创建向量。

向量共有三种:

# 数值型向量
a = c(1,2,3)
# 字符型向量
b = c("one", "two", "three")
# 逻辑型向量
d = c(TRUE, FALSE, FALSE)
# 由于R中内置了同名函数c(),最好不要在编码时使用c作为对象名,

每一个向量中的元素类型必须相同。

  • 访问元素

通过在方括号中给定元素所处位置的数值,我们可以访问向量中的元素。例如, a[c(2, 4)]用于访问向量 a 中的第二个和第四个元素。更多示例如下:

> a = c(0, 2, 4, 6, 8)
> a[1]
[1] 0
> a[c(1,3,5)]
[1] 0 4 8
> a[2:5]
[1] 2 4 6 8
#冒号可生成数值序列

矩阵

  • 创建

矩阵(matrix)为二维数组,每个元素类型相同,可通过函数matrix()创建矩阵。

> mymatrix = matrix(vector,nrow = number_of_rows, ncol = number_of_columns,
                  byrow = logical_value, dimnames = list(
                  char_vector_rowname, char_vector_colnames))

其中 vector (向量)包含了矩阵的元素, nrow 和 ncol 用以指定行和列的维数, dimnames 包含了可选的、以字符型向量表示的行名和列名。选项 byrow 则表明矩阵应当按行填充( byrow=TRUE )还是按列填充( byrow=FALSE ),默认情况下按列填充。

> row_name = c("row1","row2", "row3", "row4","row5")
> col_name = c("col1","col2", "col3", "col4")
> m = matrix(1:20, nrow = 5, ncol = 4, byrow = TRUE, dimnames =                                   list(row_name,col_name))
> m
     col1 col2 col3 col4
row1    1    2    3    4
row2    5    6    7    8
row3    9   10   11   12
row4   13   14   15   16
row5   17   18   19   20
  • 访问元素
# 访问某一行
> m[1,]
col1 col2 col3 col4 
   1    2    3    4
# 访问某一列
> m[,1]
row1 row2 row3 row4 row5 
   1    5    9   13   17 
#访问某个元素
> m[2,3]
[1] 7
# 访问行上的部分元素
> m[2,c(2:4)]
col2 col3 col4 
   6    7    8 

数组

数组(array)与矩阵类似,但是维度可以大于2。数组可通过 array 函数创建,形式如下:

myarray = array(vector, dimensions, dimnames)

其中 vector 包含了数组中的数据, dimensions 是一个数值型向量,给出了各个维度下标的最大值,而 dimnames 是可选的、各维度名称标签的列表。代码清单2-3给出了一个创建三维(2×3×4)数值型数组的示例。

> dim1 = c("A1","A2")
> dim2 = c("B1", "B2", "B3")
> dim3 = c("C1","C2", "C3", "C4")
> myarray = array(1:24, c(2,3,4), dimnames = list(dim1, dim2, dim3))
> myarray
, , 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

从数组中选取元素的方式与矩阵相同。上例中,元素 z[1,2,3] 为15。

数据框

数据框(frame)不同的列可以包含不同类型的数据,是R中最常处理的数据类型。

> ID = c(1:4)
> name = c("zhang_san", "li_si", "wang_er", "ma_zi")
> age = c("13", "43", "15", "53")
> gender = c("F", "M", "M", "M")
> studentdata = data.frame(ID, name, age, gender)
> studentdata
  ID      name age gender
1  1 zhang_san  13      F
2  2     li_si  43      M
3  3   wang_er  15      M
4  4     ma_zi  53      M
# 访问元素
# 访问一列或一行
> studentdata$ID
[1] 1 2 3 4
# 访问几列或几行
> studentdata[c("ID", "age")]
  ID age
1  1  13
2  2  43
3  3  15
4  4  53
# 创建两个变量之间的列联表
> table(studentdata$name, studentdata$gender)
           
            F M
  li_si     0 1
  ma_zi     0 1
  wang_er   0 1
  zhang_san 1 0

函数 attach() 可将数据框添加到R的搜索路径中。R在遇到一个变量名以后,将检查搜索路径中的数据框,以定位到这个变量。以第1章中的 mtcars 数据框为例,可以使用以下代码获取每加仑行驶英里数( mpg )变量的描述性统计量,并分别绘制此变量与发动机排量( disp )和车身重量( wt )的散点图:

attach(mtcars)
plot(mpg,disp)
detach(mtcars)

函数 detach() 将数据框从搜索路径中移除。值得注意的是, detach() 并不会对数据框本身
做任何处理。

因子

变量分为:名义型、有序型和连续型

  • 名义型:只表示类型,无序。如糖尿病123型
  • 有序型:有顺序关系,如好、良、差。
  • 连续型:可以呈现为某个范围的任意值,。如年龄,身高。

名义型和有序型在R中成为因子。

函数factor()以一个整数向量的形势存储类别值,同时一个由字符串组成的内部向量将映射到这些整数上。

列表

列表最为复杂,一般来说,列表就是一些对象的有序组合。列表允许你整合若干对象到单个对象名下。例如,某个列表中可能是若干向量、矩阵、数据框,甚至是其他列表的组合。可以使用函数list()创建列表:

> 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[1]
$title
[1] "My First List"

> mylist[2]
$ages
[1] 25 26 18 39

> mylist[3]
[[1]]
     [,1] [,2]
[1,]    1    6
[2,]    2    7
[3,]    3    8
[4,]    4    9
[5,]    5   10

> mylist[4]
[[1]]
[1] "one"   "two"   "three"

> mylist[[1]]
[1] "My First List"
> mylist[[2]]
[1] 25 26 18 39
> mylist[2]
$ages
[1] 25 26 18 39

本例创建了一个列表,其中有四个成分:一个字符串、一个数值型向量、一个矩阵以及一个字符型向量。可以组合任意多的对象,并将它们保存为一个列表。

你也可以通过在双重方括号中指明代表某个成分的数字或名称来访问列表中的元素。此例中, mylist[[2]] 和 mylist[["ages"]] 均指那个含有四个元素的向量。由于两个原因,列表成为了R中的重要数据结构。首先,列表允许以一种简单的方式组织和重新调用不相干的信息。其次,许多R函数的运行结果都是以列表的形式返回的。需要取出其中哪些成分由分析人员决定。你将在后续各章发现许多返回列表的函数示例。

数据的输入

现在你已经掌握了各种数据结构,可以放一些数据进去了。作为一名数据分析人员,你通常会面对来自多种数据源和数据格式的数据,你的任务是将这些数据导入你的工具,分析数据,并汇报分析结果。

image.png

1 使用键盘输入数据

也许输入数据最简单的方式就是使用键盘了。R中的函数 edit() 会自动调用一个允许手动输入数据的文本编辑器。具体步骤如下:

(1) 创建一个空数据框(或矩阵),其中变量名和变量的模式需与理想中的最终数据集一致;
(2) 针对这个数据对象调用文本编辑器,输入你的数据,并将结果保存回此数据对象中。

在下例中,你将创建一个名为 mydata 的数据框,它含有三个变量: age (数值型)、 gender(字符型)和 weight (数值型)。然后你将调用文本编辑器,键入数据,最后保存结果。类似于 age=numeric(0) 的赋值语句将创建一个指定模式但不含实际数据的变量。注意,编辑的结果需要赋值回对象本身。函数 edit() 事实上是在对象的一个副本上进行操作的。如果你不将其赋值到一个目标,你的所有修改将会全部丢失!

在Windows上调用函数 edit() 的结果如图2-3所示。

image.png

如图2-

我已经自主添加了一些数据。单击列的标题,你就可以用编辑器修改变量名和变量类型(数值型、字符型)。你还可以通过单击未使用列的标题来添加新的变量。编辑器关闭后,结果会保存到之前赋值的对象中(本例中为 mydata )。再次调用 mydata <-edit(mydata) ,就能够编辑已经输入的数据并添加新的数据。

语句 mydata <- edit(mydata)的一种简捷的等价写法是 fix(mydata) 。这种输入数据的方式对于小数据集很有效。对于较大的数据集,你所期望的也许是我们接下来要介绍的方式:从现有的文本文件、Excel电子表格、统计软件或数据库中导入数据。

> mydata <- data.frame(age = numeric(0),gender = character(0),weight = numeric(0))
> mydata <- edit(mydata)
> mydata
  age gender weight
1  23      F     45
2  56      M     78
> mydata <- edit(mydata)

2 从带分隔符的文本文件导入数据

你可以使用 read.table() 从带分隔符的文本文件中导入数据。此函数可读入一个表格格式的文件并将其保存为一个数据框。其语法如下:

mydataframe <- read.table("example.csv",header = TRUE,sep = ",")
mydataframe

其中, file 是一个带分隔符的ASCII文本文件, header 是一个表明首行是否包含了变量名的逻辑值( TRUE 或 FALSE ), sep 用来指定分隔数据的分隔符, row.names 是一个可选参数,用以指定一个或多个表示行标识符的变量。

举个例子,语句:

> grades <- read.table("studentgrades.csv", header=TRUE, sep=",", row.name="STUDENTID")

从当前工作目录中读入了一个名为 studentgrades.csv 的逗号分隔文件,从文件的第一行取得了各变量名称,将变量 STUDENTID 指定为行标识符,最后将结果保存到了名为 grades 的数据框中。

请注意,参数 sep 允许你导入那些使用逗号以外的符号来分隔行内数据的文件。你可以使用sep="\t" 读取以制表符分隔的文件。此参数的默认值为 sep="" ,即表示分隔符可为一个或多个空格、制表符、换行符或回车符。

默认情况下,字符型变量将转换为因子。我们并不总是希望程序这样做(例如处理一个含有被调查者评论的变量时)。有许多方法可以禁止这种转换行为。其中包括设置选项stringsAsFactors=FALSE ,这将停止对所有字符型变量的此种转换。另一种方法是使用选项colClasses 为每一列指定一个类,例如 logical (逻辑型)、 numeric (数值型)、 character(字符型)、 factor (因子)。函数 read.table() 还拥有许多微调数据导入方式的追加选项。更多详情,请参阅help(read.table) 。

3 导入Excel数据

读取一个Excel文件的最好方式,就是在Excel中将其导出为一个逗号分隔文件(csv),并使用前文描述的方式将其导入R中。在Windows系统中,你也可以使用 RODBC 包来访问Excel文件。电子表格的第一行应当包含变量/列的名称。

首先,下载并安装 RODBC 包。你可以使用以下代码导入数据:

library(RODBC)
channel=odbcConnectExcel("d:/test.xls")
mydata=sqlFetch(channel,'Sheet1')   

这里的 myfile.xls 是一个Excel文件, mysheet 是要从这个工作簿中读取工作表的名称,channel 是一个由 odbcConnectExcel() 返回的 RODBC 连接对象, mydataframe 是返回的数据框。 RODBC 也可用于从Microsoft Access导入数据。更多详情,参见 help(RODBC) 。

Excel 2007使用了一种名为XLSX的文件格式,实质上是多个XML文件组成的压缩包。 xlsx包可以用来读取这种格式的电子表格。在第一次使用此包之前请务必先下载并安装好。包中的函数 read.xlsx() 可将XLSX文件中的工作表导入为一个数据框。其最简单的调用格式是read.xlsx(file, n) ,其中 file 是Excel 2007工作簿的所在路径, n 则为要导入的工作表序号。

6 导入SPSS数据

SPSS数据集可以通过 foreign 包中的函数 read.spss() 导入到R中,也可以使用 Hmisc 包中的 spss.get() 函数。函数 spss.get() 是对 read. spss() 的一个封装,它可以为你自动设置后者的许多参数,让整个转换过程更加简单一致,最后得到数据分析人员所期望的结果。

首先,下载并安装 Hmisc 包( foreign 包已被默认安装):然后使用以下代码导入数据:

这段代码中, mydata.sav 是要导入的SPSS数据文件, use.value.labels=TRUE 表示让函数将
带有值标签的变量导入为R中水平对应相同的因子, mydataframe 是导入后的R数据框。

library(Hmisc)
mydataframe <- spss.get("mydata.sav", use.value.labels=TRUE)

数据集的标注

处理数据对象的实用函数

image.png

[图片上传失败...(image-9a10aa-1577187171371)]

我们已经讨论过其中的大部分函数。函数 head() 和 tail() 对于快速浏览大数据集的结构非常有用。例如, head(patientdata) 将列出数据框的前六行,而 tail(patientdata) 将列出最后六行。我们将在下一章中介绍 length() 、 cbind() 和 rbind() 等函数。我们将其汇总于此,仅作参考。

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

推荐阅读更多精彩内容