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內置的序列函數、字典