在使用R處理資料的時候,很多時候會遇到文字型態的資料,他有表達某種運算或是簡化的觀念,這邊舉一個例子,比如一比標註藥物基因體資料內容如下:“CYP2C191-10”,對我們來說,可以理解成CYP2C191到CYP2C1910,總共十筆資料,這時候該如何用R處理呢?此時便可以使用Non-standard evaluation的觀念來處理,下面是範例,這邊會使用到quote,parse,eval等在處理此類問題的函數,其實Hadley Wickham正在開發一個用來處理Non-standard evaluation的工具包Lazyeval
基本上,quote, parse, eval這三個最基本的函數便可以演示一下所謂的non-standard evalution在做什麼,簡單說就是當syntax非正常console可接受語法的時候,該如何讓其繼續發揮功能!
那什麼是expression呢?
我們每個在R command line下所寫的算式或是函數的使用,其實就是一種expression,尤其是在像R這類非常interactive的程式語言,當我們輸入進去R console時候便是讓R去將expression執行出來,也就是去evaluation expression。正常在console下打1+1,按下輸入後,便會跑出2,但假如我們的輸入是“1+1”的字串呢?那麼這就必須使用non-standard evaluation來處理這類型的問題。
比如quote和expression這兩個函數可以用來包著這樣的表示:
quote(1+1) expression(1+1)
單這樣的話,代表用來處理尚未被evaluation的expression,這是後便用eval函數來執行這些expression:
eval(quote(1+1)) eval(expression(1+1))
你也可以使用parse來將字串轉化為expression,那麼便可以執行,比如
parse(text = "1+1") eval(parse(text = "1+1"))
#處理基因變異資料的轉換,使用到non-standard evalution的觀念 "*3-*8, *11-*16, *19-*21" %>% str_split(",") %>% unlist() %>% str_replace_all("\\*","") %>% str_replace_all("-",":") %>% map(~parse(text=.)) %>% lapply(eval) %>% unlist %>% as.character() %>% str_replace_all("^","CYP2D6\\*")
另外,在處理這種將“text”轉變成為變數這件事上,assign和get這兩個函數非常好用,可以放在expression處理這部上層,來解決一些複雜變數處理的問題。assign和get兩個函數的功能剛好相反,可以參考下面的範例
assign("A",c(1,2,3) #> A #> [1] 1 2 3 assign("A",data.frame(a=c(1,2),b=c(1,23))) #> A #> a b # 1 1 # 2 23 get("A") #> a b # 1 1 # 2 23
相關閱讀參考:
Advance R:Non-standard evaluation
Non-standard-evaluation and standard evaluation in dplyr
Struggling with Non Standard Evaluation