什麼是 Expression
先分別從數學和程式語言兩個定義來看待 expression
數學上的 expression
數學上 的 expression ,就是將一些數學符號排列在一起。可以是數字(number),也可以是運算子(operator)或符號(symbol)
用一個 x + 12 來說明 expression 的組成的話,x 是符號、 + 是運算子 、12 是數字
程式語言 expression
程式的expression 基本上和數學定義是差不多的,由運算子(operator)和運算元(operand)組成,比較明顯的差異在於程式的目的是要經過電腦算出結果。一般的情況下電腦中的expression會算出一個新的值,我們可以把這個值再賦值給一個變數
x <- 12 + 5
這個語法讓變數 x 被賦予了新的值
x + 1
## [1] 18
這個語法讓x被加法操作出現了新的值,差別在於沒有將這個值賦予到一個變數上
為了不要和數學混在一起,R語言的Expression 就先稱為 R expression
Expression Evaluation
接下來講到 evaluate
前面講到一般情況下R expression會算出一個新的值,因此也存在非一般的情況。R 語言有兩個特殊的 function,分別是 quote() 和 substitute()。這兩個function 都可以將R expression 卡住,使其保留在一個沒有被運算的狀態,直到被求值(evaluate) 後才開始運算
而這個「卡住」的狀態又可以經由 eval() 來重新算出來,這就是 evaluate
quote() ,expression() and substitute()
下面來整理一些 R expression 概念下常見的 function
quote()
最簡單的形式,其本質是類似list 的一種結構
c1<-quote(x+5)
c1[[1]]
## `+`
c1[[2]]
## x
c1[[3]]
## [1] 5
expression()
expression() 可以放入不止一個的R expression
update <- expression(
x<-x +1, msg<-paste0("x=",x), print(msg))
x<-3
for(i in 1:5)eval(update)
## [1] "x=4"
## [1] "x=5"
## [1] "x=6"
## [1] "x=7"
## [1] "x=8"
substitute()
substitute 可以把 expression 設定好的變數 用list 的方式給予,所以會有這種操作
plot(0,type="n")
for (i in 1:4)
text(1, 0.2 * i,
substitute(x[ix] == y, list(ix = i, y = pnorm(i))))
plotmath
這大概是 expression 最常見的用途
plot(1:10, type="n", xlab="", ylab="", main = "plot math & numbers")
text(4, 9, expression(hat(beta) == (X^t * X)^{-1} * X^t * y))
text(4, 8.4, "expression(hat(beta) == (X^t * X)^{-1} * X^t * y)",
cex = .8)
text(4, 7, expression(bar(x) == sum(frac(x[i], n), i==1, n)))
text(4, 6.4, "expression(bar(x) == sum(frac(x[i], n), i==1, n))",
cex = .8)
text(8, 5, expression(paste(frac(1, sigma*sqrt(2*pi)), " ",
plain(e)^{frac(-(x-mu)^2, 2*sigma^2)})),
cex = 1.2)
Derivatives
主要還是拿來算 gradient
ex1<-quote(1+5*x-x^2)
ex2<-deriv(ex1,'x')
D(ex1,'x')
## 5 - 2 * x
x<-2
fx<-eval(ex2)
fdx<-.grad[1,]
fdx
## x
## 1
Non-standard evaluation
一種特殊的技巧
data(iris)
for(n in names(iris)){
print(paste0(n," = head(iris$",n,")"))
ex1<-parse(text=paste0(n," = head(iris$",n,")"))
eval(ex1)
}
## [1] "Sepal.Length = head(iris$Sepal.Length)"
## [1] "Sepal.Width = head(iris$Sepal.Width)"
## [1] "Petal.Length = head(iris$Petal.Length)"
## [1] "Petal.Width = head(iris$Petal.Width)"
## [1] "Species = head(iris$Species)"
Petal.Width
## [1] 0.2 0.2 0.2 0.2 0.2 0.4
Species
## [1] setosa setosa setosa setosa setosa setosa
## Levels: setosa versicolor virginica
參考
http://ccckmit.wikidot.com/r:calculus
https://cran.r-project.org/doc/manuals/r-release/R-lang.html
https://rpubs.com/maechler/R_language_objs
https://stat.ethz.ch/R-manual/R-devel/library/base/html/is.language.html
https://stat.ethz.ch/R-manual/R-devel/library/base/html/name.html
https://ithelp.ithome.com.tw/articles/10192146
http://web.mit.edu/~r/current/arch/i386_linux26/lib/R/library/base/html/substitute.html
https://kanchengzxdfgcv.blogspot.com/2016/12/r-eval-assign.html
https://weitinglin.com/2017/02/15/r處理資料小技巧:使用non-standard-evaluation來加速資料整理函數quot/