Re: [問題] 不會傳遞 expression 到sub-function
剛剛又試了另一種寫法也成功了
######################################################################
library('doBy')
sdSubsetFun = function(group, dVar, data) {
subf = substitute( (dVar > (mean(dVar) - 1*sd(dVar))) &
(dVar < (mean(dVar) + 1*sd(dVar))))
do.call('subsetBy', list(group, subf, data))
}
# Create Data
x = rep(c('a','b','c'), 50)
y = 1:150
tData = data.frame(aa = x, bb = y)
subData = sdSubsetFun(~aa, bb, tData)
######################################################################
雖然結果一樣,但是這應該跟我上一篇的 variable mapping 有所不同。
上一篇是直接把所有變數的 expression 都 map 到裏面的subsetBy
但是這一篇只有 dVar 會是 map 到外面的 expression
group 和 data 就沒有被 map 成外面的 ~aa 和 tData
連我自己都覺得講的好繞口...
※ 引述《cog5566 (刃之56)》之銘言:
: 感謝版主的回應。
: 我也是在看 github
: 在經過 4個小時看完這篇內容之後,
: https://github.com/hadley/devtools/wiki/Computing-on-the-language
: 我終於成功弄(湊)出來了。好感動
: ######################################################################
: library('doBy')
: sdSubsetFun = function(group, dVar, data) {
: dataOut = substitute(
: subsetBy(group,
: (dVar > (mean(dVar) - 1*sd(dVar))) &
: (dVar < (mean(dVar) + 1*sd(dVar))),
: data = data)
: )
: eval(dataOut)
: }
: # Create Data
: x = rep(c('a','b','c'), 50)
: y = 1:150
: tData = data.frame(aa = x, bb = y)
: subData = sdSubsetFun(~aa, bb, tData)
: ######################################################################
: 重點是要用 substitute 包住全部的 code
: 而 substitute 很奧妙,它會替換裏面的 variable name 去對應
: 可能的值,然後輸出 language object
: 有趣的是如果吧 substitute() 改成 quote()
: 就不會替換成值。我也是現在才終於知道這兩個關鍵性的差別。
: ※ 引述《Wush978 (拒看低質媒體)》之銘言:
: : 以下是我最初推文時測的code
: : ```r
: : library('doBy')
: : sdSubsetFun = function(group, dVar, data) {
: : sdVar = substitute(dVar)
: : # 2SD threshold
: : subsetThreshold <- substitute( (sdVar > (mean(sdVar) - 2*sd(sdVar))) &
: : (sdVar < (mean(sdVar) + 2*sd(sdVar))) )
: : data$temp <- eval(subsetThreshold)
: : dataOut = subsetBy(group,
: : subset = temp,
: : data = data)
: : }
: : # Create Data
: : aa = rep(c('a','b','c'), 50)
: : bb = 1:150
: : tData = data.frame(aa,bb)
: : subData = sdSubsetFun(~aa, bb, tData)
: : ```
: : 不過應該和Chris7462的修改類似。
: 是類似,但還是不一樣。Chris7462 一直試圖在 function 外弄出多餘的變數,
: 來讓他的程式假性的沒有出錯。
: 在後來的回文我改了一個地方讓變數不會造成混肴
: x = rep(c('a','b','c'), 50)
: y = 1:150
: tData = data.frame(aa = x, bb=y)
: subData = sdSubsetFun(~aa, bb, tData)
: 版主的程式會 work 是因為它在這一行
: data$temp <- eval(subsetThreshold)
: eval 會去 evaluate bb這個變數。
: 但是其實 fuction 內沒有 bb 這個變數的,所以 R 會去外面抓 bb
: (這點我也是很不習慣這種 scoping 的方式)
: 剛好外面有 bb 所以看起來沒有出問題。
: 但是其實這個寫法出來的答案會是錯的,因為這時候 sd 是由 1:150來算的,
: 因為是抓 bb = 1:150
: 而不是依組別算的。
: 現在把function 外變數改成這樣x,y的話,就會出錯。因為fuction 外面其實沒有 bb
: bb 是在 tData 裏面的變數,如果沒有 attach() 到 search path,
: 是根本抓不到的。
: ======================================================================
: 總結來說,就是有沒有辦法設計一個 function 他是可以照組別刪去
: data frame 特定 variable 的 2sd 之外的資料呢?
: 我希望在我有一個 data frame tData 的情況下,
: sdSubsetFun 這個 function
: sdSubsetFun = function(group, dVar, data)
: 的 dVar 的引數輸入的時候,我可以直接放 data frame 的 variable name
: 而不用利用 attach() 或是做出而外的變數來達成我的目標。
: 因為 subset, subsetBy 等等的也是這樣就可以做到
: 一個解答就是以上的 code
: 我不知道有沒有更好的解法,如果有也請多指教。
: 我覺得 R 在這一部份可能跟 fucntional programming 有關的實在很複雜。
: : ---
: : 關於物件的是屬於symbol或character,也就是後來cog5566提到關於`rm`函數行為的問題,
: : 這也是我過去學R ,到目前覺得很不可思議和不方便的地方。
: : cog5566可以用以下的方式來探索函數的行為:
: : ```r
: : debug(rm)
: : x <- "y"
: : y <- 10
: : rm(x)
: : ```
: : 這之後會進入除錯模式,你可以巨細靡遺的觀察`rm`函數的行為。
: : 你會發現有種叫作"name"型態的物件。
: : 也可以去追相關函數的說明文件,也許你就可以搞清楚了。
: : ps. 我最近事情有點多,就沒追下去搞懂他了。
: : 我也不太確定Hadley的R advanced裏面有沒有提到這件事情。
: : ps. 現在github好像掛了,晚點我再補連結。
: : 期待你搞清楚後也可以播空發篇文章教教我,先謝謝了。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 139.184.222.89
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 8 之 8 篇):
R_Language 近期熱門文章
PTT數位生活區 即時熱門文章