好,那么我们上次课花了一节课帮助大家解决了很小的几个问题,就是知道什么是工作路径、什么是工作目录以及什么是目录、相对路径和绝对路径。然后在理解了这些概念之后,我们第一次读取了一个数据。
这节课我们讲一下在R里面,它到底有哪些数据类型,我们如何得到进行操作。我们上节课很快地讲完了R的数据类型,但大家当时可能听得很懵。如果我们按照讲R语言的方式,它会一直都是很懵。为什么呢?因为它跟我们的数据完全是脱节的。所以这节课我们通过对数据进行操作,进行数据筛选的学习。上次课我们已经读取过数据,这次我们将按照相同的方式再次读取数据。
我们将使用read.csv来读取三个数据,并将它们合并。在这里,我们有三个数据文件,分别是707304、7305和7306。我们的分隔符与上次不同,我们使用空格而不是制表符。在空格中间,有两个引号
(““)
。我们这次的数据分割方法与上节课不同。上节课我们使用了斜杠和t作为分割符号,但是我们发现使用tab作为分割符号时会出现问题,无法真正进行分割。因此我们进行了尝试,发现使用空格作为分割符号更为合适,空格中间有两个引号,不加任何东西。这与上节课不同。
刚刚我们使用了R-bind函数将三个对象合并成一个,这涉及到函数的概念,我们在前面已经讲过。数学中的函数实际上就是一种方法,只不过是用代码来实现。数学函数可以表示为y=f(x),或者其他形式,其中括号内是我们输入的变量,它会返回一个结果。在R语言中,函数也基本上是这个意思,就是有一个特定的名称,比如在这里就叫做rbind,然后有一个括号,你在这个括号内输入内容之后,它就会返回一个结果。
函数是用于执行特定任务或计算的代码块,它接受输入参数,执行特定的操作,然后返回结果。函数来源有很多,安装R时,我们一般会安装R-base,这是R开发团队放在R基础包中的所有东西。这个base中已经包含了很多用于统计分析的函数。另外还有R的包,就是我们自己额外安装的包,比如Tidyverse、GGPlot、Nymer、Lmer、Lme4等。还有其他的R源,比如Cray、Microsoft、Stand等。除了这些,还可以在GitHub上直接安装一些包。虽然函数可以自己编写,但这比较复杂,我们会在后面再讲解。
我们经常需要重复执行某个任务,这时可以将其封装成一个函数,以后只需要调用这个函数即可,无需重复编写所有操作。函数是一个重要的知识点,可以用非常简单的两三行代码实现。但是有时候,当我们使用别人提供的函数时,可能不知道它的作用、输入规则和选项。在RStudio中,我们可以通过在函数名前加一个英文问号来查看它的用法。例如,在使用here包时,我们可以在RStudio的右下角看到帮助文件。
qiuzhu2
但是有些帮助文件可能并不是很有用,因为开发者有时会有所谓的“知识诅咒”,认为别人都和他一样有基本知识和内容。这时,我们可以在搜索引擎中搜索关键词和R包名,以便找到我们需要的信息。在调用已有的函数 时,我们需要先使用library加载包,然后直接使用函数名和小括号。如果没有加载包,我们可以直接使用R包名和两个冒号加上函数名来调用。个人偏好是将包名加上,因为R的生态系统非常复杂,有很多包都有类似的功能,这样可以避免混淆。
因我们需要使用 filter 功能来筛选我们需要的数据。在本次实验中,我们采用了一个例子,以帮助大家更好地理解数据分析中的 filter 形式及使用方式。
最简单的方法是根据我们所拥有的变量来进行筛选,我们已知其中一个变量可以带来非常明显的效益,即匹配和不匹配的情况。在三个被试中,我们需要进行基本的查看,以确认其匹配和不匹配条件是否相同。为了进行这种分析,我们需要将原始数据分成两部分,即匹配和不匹配。
对于这个 data,我们可以使用 Dplyr 中的 filter 功能,以实现对数据的筛选。filter 的第一个参数是需要操作的数据集,而第二个参数是所需的筛选条件。对于本次实验来说,我们需要使用 filter 函数来提取匹配和不匹配条件相同的数据,即我们需要从 match 数据中提取所有 non-match 或 mismatch 数据。为了保证我们选择的数据正确,我们可以使用 unique 命令来进行检查,如果我们成功完成了筛选,则 unique 命令会返回一个值(即 mismatch)。
R中有一些用于比较的运算符,例如大于、小于、大于等于、小于等于。这些都是在做基础知识时非常重要的东西,我们可以在这里稍微细致地介绍一下。
在R语言中,我们还有一个特殊的运算符,就是!。我们在命名变量时,不能使用这个!,因为它表示的是不等于。例如a不等于b,实际上是先有一个等于符号,然后再用一个感叹号表示否定,这样它们就不相等了。我们这里使用的是两个等于号,表示完全相等的两个元素。
bijiao
有人会问,大于小于只能用于数字吗?实际上并不是这样。我们可以使用字符进行比较运算,但是要特别小心。因为有的时候你以为它在做数字运算,但它实际上是基于字符运算的。因此,我们需要在使用时格外注意。
在R语言中,还有一个非常有用的操作符,就是in。它是一个函数,用这个符号代表。它的作用是判断a是否是b中的一个元素。这也是我们在上一节课上讲到的概念,“向量”,它是一个一串的数字,我们需要找到其中的某个值。这时使用in操作符就可以帮助我们查找所有满足条件的值的位置。in操作符在R语言中非常受欢迎,因为它能够快速帮助我们找到一些特定的值。
在比较运算的时候,我们涉及到了“vector”。我们之前讲过,它就是一些数据的类型。但是对于“vector”而言,它有一个特点:里面的所有元素必须是同一个类型的。我们提到的有逻辑型、整型、双精度,字符型等类型。如果要把一些元素放在一起,那么它们应该都属于同一个类型。如果不是同一种类型,我们就可能需要使用其他类型的数据来存放它们。
回到刚才的代码,当我们使用“filter”操作数据时,我们是通过比较数据中的“match”这一列和“mismatch”这个字符串来得到的结果。因为我们需要把它与每一个对象进行比较,所以每个对象都会有一个输出。因此,我们得到了一个逻辑型的“vector”。我们可以把它们连成一个向量。在这个“match”中,我们可以使用“class”函数来查看某一列的数据类型。比如,我们查看一下刚刚的“match”是什么类型的,我们可以发现,它是字符类型的,它的输出结果是“correct”。对于其他类型,我们也可以做类似的查看。当然,字符类型除了“=”操作符外,还有其他方式可以用来确定它是否精确匹配。
## [1] "character"
新的DataFrame是根据条件筛选出的子集。在处理DataFrame时,我们可以按步骤来处理。如果没有现成的函数能够直接解决问题,我们可以通过自己的思考,将筛选过程拆成一个个小的步骤,逐步解决问题。首先,我们要提取出一个column,然后将column中的每个元素与条件进行比较。比较结果可以得到一个新的vector。接着,我们可以通过vector中的rowid提取出符合条件的ID,再从原始数据集中提取出对应的子集。如此,我们就完成了整个筛选的过程。再刚刚的过程中机器会自动将我们的需求划分成小的步骤来处理。
除了字符之外,我们也可以对数字进行筛选。首先需要将字符串类型的“acc”转换为数值型的变量。我们可以查看变量类型,如果是字符型,我们可以使用“as.numerical”的函数将其转换为数值型。通过match data.all这个命令,我们可以获取到一个字符型的vector”acc”,将其转换成数值型后,我们将其赋值给另一个名为”acc”的变量。这样,我们就将”acc”变为数值型了。通过查看unique命令,我们可以发现”acc”共有”-1,0,1,2”这几个值。我们可以将大于0的值作为筛选条件,这样筛选过的变量中只保留了0,1,2这几个值,从而完成了数字的筛选过程。