第1章 R数据科学:数据框的操作
从一名语言研究者的角度看,使用R*根本的目的应该是统计分析(即构建统计模型)和数据可视化(即作图)。不管是统计分析还是数据可视化,从根本上都要求对变量(variables)进行操控。本质上,统计建模就是对变量之间的关系进行量化处理,而可视化则是将变量之间的关系映射到图形上。这就意味着,在进行统计分析和数据可视化之前,研究者必须把实验所获得的原始数据进行清洁和整理,让它变成一张“干净、整洁”的数据表,表上能够显示独立的变量名,以便统计分析时直接引用。即使是*有经验的研究者都可能认为这个过程是一次完整的数据分析中“*麻烦、*艰难”的过程,总是耗时费力。通常情况是,统计建模或数据可视化只要几分钟就能搞定,而把数据整理成能够用于统计建模或可视化的“干净、整洁”数据表则可能需要花费几个小时,甚至几天的时间。在R语言中,有一个专门的术语来称呼这张“干净、整洁”、可用于统计建模和可视化的数据表,即数据框(data frame)。
在笔者看来,数据框的操作能力是掌握R语言需要具备的*基本、*不可或缺的能力。当一个人具备高超的数据框操作能力时,他往往也已经具备一定的实验能力,已经形成了很强的“变量”意识,能够从变量之间的关系去审视数据。同时,也只有通过反复的练习,一个人才能达到高超的数据框操作能力,才能对R的工作机制形成比较完整的理解,而这种理解会给统计建模和数据可视化带来极大的便利。
何谓高超的数据框操作能力呢?从R语言使用者的角度来看,就是能够自如地让数据框根据自己的意图任意转换,转换成自己想要的“样子”。比如,能够轻易把一张极其混乱、毫无章法的数据表变得“干净、整洁”,能够自如地对变量进行命名、变化、转换,能轻易地把不同的表格进行合并,等等。那么,如何才能达到高超的数据框操作能力呢?笔者认为主要有以下四点:
(1)深刻理解适用于R工作环境中“干净、整洁”的数据框的标准;
(2)非常熟练地使用一些数据框操作函数;
(3)具备一些基础的正则表达式的知识,能够对文本数据进行操作;
(4)能够熟练地对各种数据表格进行合并或拆分。
下面将分别就以上四点进行详细介绍。
1.1 “干净、整洁”的数据框的标准
上文说过,统计分析的两个关键过程——统计建模和数据可视化,都是通过操作数据框中的变量来实现的,可见变量是数据框的关键元素。相同的数据,可以有很多不同的表达方式,但是变量如何在数据框中呈现,是判断数据框是否“干净、整洁”的重要标准。Wickham和Grolemund(2017: 149)给适合于R语言的“干净、整洁”的数据框划定了三条标准,即:
(1)每一个变量(variable)必须有它自己的列(column)。
(2)每一个观测(observation)必须有它自己的行(row)。
(3)每一个值(value)必须有它自己的单元格(cell)。
正如上面提到的,数据整理是数据分析的前提,这三条标准可以成为完成研究实验后,整理原始数据的重要依据。如果读者已经具备一定的数据科学知识就会意识到,这三条标准其实是相互关联的,因为实际上数据整理不可能只满足上述两条标准而不满足第三条标准。
为了帮助读者理解这三条标准的内涵,不妨先参考和学习Wickham和Grolemund(2017: 148-149)提供的内容相同但是呈现方式各异的5个表格。这5个表格呈现了世界卫生组织所记录的在1999年至2000年间发生在阿富汗(Afghanistan)、巴西(Brazil)等国的肺结核(TB)的病例数 。这5个表格的名字分别为table1,table2,table3,table4a,table4b。
先加载tidyverse包,然后在RStudio的代码编辑区输入以上表格的名字,按下Ctrl+Enter即可查看到各个表格的内容,如下:
library(tidyverse)
table1
## # A tibble: 6 x 4
## country year cases population
## <chr> <int> <int> <int>
## 1 Afghanistan 1999 745 19987071
## 2 Afghanistan 2000 2666 20595360
## 3 Brazil 1999 37737 172006362
## 4 Brazil 2000 80488 174504898
可以看到table1是一个6行4列tibble格式的数据表格,这个表格看起来非常 “规整”,行和列之间排列紧凑,清楚地显示了哪一个国家,在哪一年爆发病例的数量以及这个国家这一年的总人口数。比如,Afghanistan在1999年TB病例为745例,这一年这个国家的总人口数是19,987,071。这个表格符合本书称之为“干净、整洁”的数据框的标准,因为它满足了三个相互关联的标准。
首先,每一个变量都必须有它自己的列或者反过来说,每一列都代表一个独特的变量。table1一共有4列,每一列都代表一个变量:country,year,cases,population。第一个变量country(国家),是字符型变量(<chr>),第二个变量year(年),为整数型变量(<int>),第三个变量cases(病例数),是整数型变量(<int>),*后一个变量是population(人口),也是整数型变量(<int>)。这就是tibble格式的数据框与传统的数据框的不同之处,它会清楚地显示每一个变量的类型。关于tibble和传统数据框的区别大家可参照《第二语言加工及R语言应用》一书所给出的详细解释。
正如上文所说,“变量”意识对数据分析至关重要,从“变量”的角度去整理和“审视”自己通过实验所收集到的数据会让思路变得清晰和简单。有必要在这里简单解释一下“变量”这个重要概念。顾名思义,“变量”就是指会变化的度量,Gravetter和Wallnau(2017: 4)提供了一个更正式的专业化定义:
变量是一种特征(characteristic)或状况(condition),会发生改变或者每一个个体都有不同的值。
可见,“变”是变量*典型的特点。比如,table1中country这个变量就有3种不同的变化或者说有3种不同的值,即执行代码后显示的3个国家。year这个变量有2种不同的变化或者说2种不同的值,即1999和2000。
变量按不同的标准,分成不同的类别。比如table1中的4个变量就有两种不同的种类,即字符型(<chr>)和整数型(<int>)。这种分类是RStudio对导入的数据所进行的分类,但是针对具体的数据通常人们从总体上把变量分成三大类:①名义型变量(nominal variables)。比如,词类可分为动词、名词、形容词等,性别可分作男和女,词类以及性别就属于名义型变量。②定序变量(ordinal variables)。比如,把学生的外语水平分成高、中、低,把高铁的座位分成一等、二等,那么可进行比较的语言水平以及高铁的座位就可称作定序变量。③定比变量(ratio variables),亦称数值型变量。比如,学生的成绩,测量被试行为反应的反应时等。定序变量与定比变量(或称数值型变量)的区别在于定序变量可按如高、中、低等排序,但是不能加减,而定比变量(或称数值型变量)却可以加减。
一般又把名义型变量和定序变量统称为分类变量(categorical variables)。这样一来,变量就被分成了两类,即分类变量和数值型变量(numerical variables)。table1中的字符型(<chr>)和整数型(<int>)变量就分别属于分类变量和数值型变量。分类变量的每一个变化也称作水平(level)。比如,country有3种不同的变化(值),即3个国家,因此country这一变量被认为有3个水平。而对于数值型变量,比如table1中的整数型变量,它的每一个变化一般称作值,比如变量cases就有6个不同的值。
当我们开展实验研究的时候,有两个通用的术语来称呼变量,即自变量(independent variables)和因变量(dependent variables)。自变量是在进行实验研究时会引起实验结果出现变化的因素,因此也是实验过程中需要操控(manipulate)的变量;而因变量则是指由于自变量的改变而受到影响的变量。比如,研究者想研究某种新的教学方法是否会显著提高中国学习者英语单词的学习效果时,教学方法就是自变量,是实验中需要进行操控的变量,比如让有的班级接受新的教学方法,有的班级接受传统的教学方法,并保持两个班级除教学方法之外的其他因素尽可能等同,等等。在这个例子中,因变量就是因使用了不同的教学方法而造成的英语单词的学习效果(可能是词汇测试成绩)。
要引用数据框中的变量,即列,方法有很多,*常用的方法是:数据框名+$+变量名,比如引用country这一变量。
table1$country
## [1] "Afghanistan" "Afghanistan" "Brazil" "Brazil"
或者数据框名+[ ],如:
table1[,1]
## # A tibble: 6 x 1
## country
## <chr>
## 1 Afghanistan
## 2 Afghanistan
## 3 Brazil
## 4 Brazil
中括号[ ]里放入数字,但此时要特别注意中括号里逗号的位置,逗号前面的数字表示的是行,若用空白则代表所有行,逗号后面的数字表示列,即变量,也可用空白,代表所有列。当然,也可以使用attach( )函数先加载数据框,然后直接使用变量名引用这个变量:
attach(table1)
country
## [1] "Afghanistan" "Afghanistan" "Brazil" "Brazil"
不过,如果一旦通过attach( )加载数据框后,如果后面不再使用这个数据框,建议养成一个良好的习惯,使用detach( )函数把数据框从当前的工作环境卸载。
detach(table1)
接前面再回到table1这个数据框。
其次,“干净、整洁”的数据框的三个相互关联的标准中的第二个标准是:每一个观测(observation)都有它的行(row),或者反过来说,每一行都是一个观测。在table1中,第一、第二行就是对Afghanistan的观测,第三和第四行是对Brazil的观测。正如上面所介绍的,引用每一个观测(行)的方法是:数据框名+[ ]。这个时候需要注意的是把数字放在中括号中逗号的前面,如:
table1[1,]
## # A tibble: 1 x 4
## country year cases population
## <chr> <int> <int> <int>
## 1 Afghanistan 1999 745 19987071
*后,“干净、整洁”的数据框的三个相互关联的标准中第三个标准是:每一个值(value)都必须有它的一个单
展开