R语言同其他语言一样,在软件启动时,为我们提供了7个核心包,包括了众多的基础函数,如 数学计算函数,统计计算函数,日期函数,包加载函数,数据处理函数,函数操作函数,图形设备函数等。通过search()函数,可以查看到R启动时默认加 载7个核心包。
掌握这种对应关系的意义在于,因为R是解释型语言,我们可以通过传递一个函数A的句柄,让其他的函数B动态调用这个函数A,这就是动态语言中的闭包特 性的使用思路。在Javascript中,已经被广泛使用了,但在R语言中,却只有核心包的一些函数在使用这种语法。在R语言中,这种需要有计算机背景知 识的地方还有很多,特别是在考虑如何提升R性能的部分。所以,不要太轻易就说自己掌握了R语言,多想想如何才能把其他语言的基础带到R语言的世界里。
R语言的内核编程
R语言的内核编程,又是一个比较复杂的计算机学科的问题。R的内核编程应该包括哪些内容呢,除了刚才说的R的语法和R的核心包,还有面向对象编程,量 向化计算,特殊数据类型,环境空间等。我的第二本书《R的极客理想-高级开发篇》将会重点介绍这部分的内容。
面向对象编程,是一种对现实世界理解和抽象的方法,主要用于解决复杂问题的设计及实现。在Java的世界里,从2003年开始我接触Java的时候, 社区就已经在聊面向对象的程序设计了。对于R语言来说,直到2011年发布的2.14版本,才最终有了RC类型的面向对象实现。面向对象的成熟,标志着R 已经具备了构建复杂大型应用的能力,但如何真正地把面向对象用好,似乎也并不是统计人擅长的。有能力写出像Hadley Wickham面向对象代码的人,在R的圈子里,实在是极少数的。
量向化计算,是R语言特有的一种并行计算方式。在R中,向量是R的基本数据类型(vector),当你对一个向量进行操作时,程序会对向量中每个元素进行分别计算,计算结果以向量的形式返回。比如,最常见的两个等长的向量相加。
通过运行程序,我们可以清楚地看出,向量化计算要比循环快。当算法越复杂数据量越大的时候,计算的时间差距会越明显的。R的编程中的一条法则就是用向量计算代替所有的循环计算。
特殊数据类型,R语言中除了那些基本的数据类型,还有一些高级的数据类型,并不是不常用,而是你不知道。
S3类型,S4类型,RC类型分别对应R语言支持的三种面向对象编程的数据结构
环境类型(environment),由内核定义的一个数据结构,由一系列的、有层次关系的框架(frame)组成,每个环境对应一个框架,用来区别不同的运行时空间(scope)
可能还有我不知道的类型…(请发现的同学通知我!)
环境空间,在进行R包开发时,是必备的一个知识点。每个环境空间都是环境类型的一个实例。每个R包都会被加载到一个环境空间中,形成有层次关系的、可调用的空间结构。
我们定义的函数和变量,都会存在于R的环境空间中,通过ls()就可以看到当前环境空间中的这些变量,比如,刚才量向化计算定义的变量和函数。
除了我们自己定义的变量和函数,环境空间中还有很多其他的变量和函数,比如sum(), length(), system.time()等,这些函数我们可以直接使用,但是它们并不在当前环境空间中,所以直接用ls()是查看不到的。当我们切换到base的环境 空间时,就可以找到sum()的函数定义了。
R语言内核编程,如同其他语言一样,有很多的知识细节,并不是只有我提到的这几点。但由于缺少文档,同时R核心技术的不普及,所以知道的人就不多,会用的人更少。我也在每天探索,期待发现更多的秘密。