R语言笔记

R语言笔记

学习R语言对我来说有好几个地方需要注意的,我觉得这样的经验也适用于学习其他的新的语言。

语言的目标

我理解语言的目标就是这个语言是用来做什么的,为什么样的任务服务的,也就是设计这个语言的动机。比如C++是为系统编程服务的,java是为企业级应用服务的。R语言是用于统计分析,这样在R的系统中有大量的库(或者是package)用来实现特定的统计方法。

基本的数据类型

学习各个语言的第一步是了解这个语言的最基本的数据类型,这决定如何使用变量进行计算。

基本数据类型是直接由语言本身所定义的变量类型。基本数据类型类比于建筑工地上的沙子,你可以建高楼大厦,可以建别墅,但是你没法建沙子啊!!!或者类似于原子,完全不可再分的东西。R语言的基本数据类型包括:

  1. character:字符串类型。
  2. numeric:浮点数,应该是双精度浮点数。
  3. integer:整数
  4. logical value:TURE/FALSE两种
  5. fucntion:函数也是R语言中的基本类型

有NA和NaN两个特别的数据类型,用来表述数据无法获得和不存在这两种情况的。这个也是R语言的特色,一般语言中只存在一种表示非法的数据。

这些数据类型和C语言中的数据类型没有本质的差别。对于“character”,其实是字符串,因此在R语言中没有单个字符和字符串的区别。在基本的数据类型上各个语言可能不会有什么差别(有些语言比如MATLAB,矩阵也是基本数据类型)。

常用的数据类型

学习完基本的数据类型后,下一步应该了解的是这个语言最常用的数据类型。R语言中最常用的数据类型包括:

  1. vector:n个相同数据类型的变量,可以使用vector或者c创建。
  2. list:vector的增强版本,这n个对象可以是不同的数据类型。使用list函数创建。
  3. matrix:矩阵,nxn个相同数据类型的变量在一起,使用matrix创建。
  4. data.frame:类似于矩阵,但是每一列的数据类型可以不同。一般使用data.frame函数创建。
  5. factor:这种数据类型类似于enumeration,但是可以存在顺序,一般统计中用于数据的分类或者排序等等。
  6. Datetime:处理日期时间相关的数据。

对于vector和list来说,相比于C语言,R语言也使用整数下标做索引,但是从1开始,也同样使用"[]"。

对于list,有另外的特别的索引方法:[[]]。这种特别的索引方法正好可以给出R语言作为统计用途的语言与C的差异。R语言可以使用“名字”来对变量进行引用。可以使用名字的原因是统计表格中的每一列一般是有标题的。这样就可以直接使用标题来引用对应的数据。这样的方法对于matrix和data.frame都有效。

对于matrix和data frame来说,索引特定元素的方法是a[i,j],这种方法和c语言也不相同。另外R语言中的各种类型的函数可以使用as函数进行转换。

执行流控制语句

这个也是每个语言的必须的要素,包括判断,循环和跳转语句,这在各个语言中是不一样的,每个语言都有自己的特色,但是基本和C语言相同。

R语言的判断

  if(expression){
                expression A
        } else {
                expression B
        }

其中else部分可以省略。R语言中可以产生逻辑结果的操作符有==, !=, >, <, %in%等。

R语言提供了多种类型的循环语句

  for(index in sequence){
                expression
        }

        while(expression){
                expression
        }

        repeat {
                expression
        }

其中需要到repeat就是一个死循环,需要使用break才能从结束循环。

类似于MATLAB,在R语言中循环语句是相当的耗费时间的,如果有可能,应当尽量使用*apply函数。

函数

R语言的函数也是基本数据类型的一种,因此被称为first-class citizen。这意味着函数和其他的变量没有什么本质的不同,这一点不同于C语言。另外R语言中的函数允许嵌套定义,而且允许函数中存在函数体内部和全局环境都不可解析的变量,这对于C语言是完全不可接受的,这些在函数体内部和全局环境都不可解析的变量,称之为“free variable”。对于R语言的函数,最重要的知识点就是scoping rule:

a <- 20
f <- function(b){
        g <- function() { a + b}
        g()
}

h <- function(){
        a <- 200
        b <- 100
        f(3)
}

从函数f的定义中我们可以看出\(a\)是free variable,然后在函数h中,我们调用f,同时h内部也出现了变量a。在这个时候,lexical scoping法则规定,这些free variable的取值由函数定义所在的“环境"决定。R语言中的环境定义为一个data frame,里面存储的是一对对的”符号“和”对象“。一个环境可以有父环境,最终的根节点是一个空的环境。因此在任何R的函数对象中必然存在指向环境对象的指针,以用来解析函数中存在的free variable。因此任意符号的解析必然由环境决定的。在上图的调用中,最终的结果是23。

惯用法

相比于前面介绍的基本数据类型,常用数据类型,函数定义(或者是对象定义),这些在每个语言中可能采用不同的规则,但是基本大同小异。如何区分一个初学者和熟练使用的差别,就在于是否会恰当的使用惯用法。各个语言由于特性的不同,对于同一个事情的处理,会有完全不同的处理方法,尽管可以使用一种非常统一的方法在各个语言中实现,但这样的行为注定是要受到鄙视的。

R语言中的惯用法就是*apply函数,这些函数使用的熟练程序,对一个程序的美观可以有很大的影响。主要包括:

  1. lapply/sapply
  2. tapply
  3. mapply
  4. apply

这些函数的用法非常类似于map这种语言,对不同的对象施加同一个操作。

其他

其他的信息包括一些统计时间,获取帮助str,确定程序的热点Rprof。R语言的另一大特色是大量随机事件相关的函数。

总结

在学习新的编程语言时,一般得注意到基本数据类型,常用数据类型,函数定义,变量解析和惯用法。这样基本可以快速的使用一个语言,但是熟练使用仍然需要很长的一段时间。