R語言進階 | 非標準計算base

R語言的非標準計算在做初步數據分析應用的不多,但是會給分析工作帶來便捷。

這個系列是主要是閱讀和學習R官方的R Language Definition,還有Hadley Wickham寫的Advanced R,還有tidyverse官方的資料的筆記。

Hadley Wickham說非標準計算的最終目的是進行元編程。我理解的元編程就是操作代碼的技術,編寫像字元串文本一樣操作目標代碼的代碼。

學習這個的主要目的是寫一些比較便捷的代碼,實現常規方法不好實現的需求。

本系列計劃:

  • 原生的非標準計算,主要是base包的函數
  • tidyeval,rlang包提供的非標準計算
  • 一些簡單的實際應用

這一部分主要講在R base包中的一些函數,這些函數實現了R語言的非標準計算。

- 語法解析:substitute(), parse(), deparse() n- 表達式構造:quote()n- 表達式求值:eval(), source()n- 表達式:expression()n

parse

parse主要負責把字元解析為R語言表達式。表達式是可以被求值的代碼。n

可以看出來是一個表達式expression。

在R中解析有三種不同的變種

  • The read-eval-print loop
  • Parsing of text files
  • Parsing of character strings

read-eval-print 是讀入文本,然後進行解析,然後求值,最後列印,這個就是我們日常看到的命令行操作。

解析文件是parse函數來完成。

解析字元串就是parse中用text參數來表示。

deparse

deparse是相反的,是把R表達式逆解析為字元。

quote

quote則是捕捉未計算的表達式。

eval

quote是捕捉表達式,不進行計算(求值),將由eval來完成對表達式進行計算(求值)。

一般是用parse從字元串(或者是硬碟上的文件)解析成一個expression對象,是表達式列表,不是一個表達式。expression也可以手動構建表達式,但是Hadley Wickham不贊成這麼寫。

首先使用parse()函數將字元串轉化為表達式(expression),而後使用eval()函數對表達式求解。

?evaln# Evaluate an R expression in a specified environment.n# Usagen# eval(expr, envir = parent.frame(),n# enclos = if(is.list(envir) || is.pairlist(envir))n# parent.frame() else baseenv())n# evalq(expr, envir, enclos)n# eval.parent(expr, n = 1)n# local(expr, envir = new.env())n

表達式的操作和計算

下面這個就實現了表達式的操作和計算。

本來是1+2的表達式。表達式可以像list一樣來操作。

下面可以操作這個表達式,變成1-2。

下面這個可以再次變成1*2。

但是如果被計算的對象沒有找到,那麼會出錯。

這個給a賦值,後就可以順利計算。

即使變數是存在的,但是如果變數換了一個新環境,直接計算是錯誤的。

必須指明環境才可以。

父環境與子環境。

這個說明,在eval時遇到未定義的變數時首先是全局環境,如果有指定環境,則進入指定環境找,還會跟根據需要找到子環境的父環境中去。

綜合性例子

quote是捕捉未計算的表達式,expression是表達式。

這裡發現,各個函數生成的對象不完全相同。如果需要深入理解差異性,需要仔細閱讀R官方手冊和源代碼。

對表達式進行求值。

下一篇文章介紹Hadley Wickham等開發者傾力打造的tidyeval。rlang包實現這一功能,為tidyverse生態服務,所以又稱tidyeval。


推薦閱讀:

AllMusic 藝人資料頁中,與該藝人之間「影響/被影響」的數據是如何得到的?
銷售數據分析應該怎麼做?
20170404Python內置的序列函數、字典

TAG:R编程语言 | 数据分析 | 元编程 |