Re: [問題] 不會傳遞 expression 到sub-function
感謝版主的回應。
我也是在看 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好像掛了,晚點我再補連結。
: 期待你搞清楚後也可以播空發篇文章教教我,先謝謝了。
: ※ 引述《cog5566 (刃之56)》之銘言:
: : ...嗯...
: : 你覺得... subsetBy 的範例有用 attach() 嗎?
: : 就是因為他沒有用,所以才酷的...
: : 當然啊...因為你加了 attach() ...
: : 你把 dietox 拿到 search path 當然這個時候 Weight < mean(Weight)
: : 就可以被 evaluate。
: : 這不是等於說,你問我有沒有看到一隻貓,我說沒有。
: : 然後你放了一隻貓在我前面,再問一次有沒有看到一隻貓...
: : 然後說我之前錯了,這裡其實是有一隻貓的...
: : 這很有趣...
: : 不過講正經的,這真的不是 attach() 的問題。
: : 從頭到尾都沒有必要 attach dietox 到 Search Path
: : 我很懷疑你自己有沒有真的執行過沒有 attach() 的範例
: : 是真的可以執行的。跟 attach() 沒有關係。
: : 那
: : x <- 10
: : 請問 sum(x,x) 跟 sum(10,10) 會不會一樣呢?
: : 所以你有試過 rm(y) 嗎?
: : 你覺得答案是?
: : 答案是 y 會被刪掉而不是 x
: : 但是爲什麽這個時候 y 不會被替換成 'x'變成 rm('x') 而刪掉 x?
: : 答案是這個完全決定於 rm 的內部寫法。也就是說使用者沒辦法在外部決定輸入值是
: : variable name 或是 value。
: : 我不知道這有沒有嚇到你啦,但是我第一次看到這個是有被嚇到啦。
: : 可能我還太嫩了。
: : 這邊我想我們各有一半的責任。
: : 我的責任是說錯了一點 data frame 應該沒有包含一個 environment,就只是變數
: : 和值的對應關係。
: : 你的責任是你小小作弊式的用了 attach() 然後再做
: : typeof(Weight < mean(Weight))
: : 不然實際情況這個應該會出錯,然後會很驚訝的覺得爲什麽
: : subsetBy(~Evit, Weight < mean(Weight), data=dietox) 卻不會有問題
: : 但是這是我的最終問題呀。可能是我表達不好,不過你看不懂是如何回答的?
: : 沒錯這是個問題,而且是大問題。但是你有看到我貼的 error message 嗎
: : 在這個問題發生之前上面就出問題了。
: : 這真的不是這個問題
: : 這個有趣...
: : 你這樣可以跑是因為你用了跟剛剛加了 attach() 的作弊方式
: : aa <- x
: : bb <- y
: : 這跟 attach(tData) 是類似的意思
: : 但是這跟原本的 subsetBy那種寫法意思就差多了。
: : 我要的是 bb 不是單純的 value 代進去sdSubsetFun
: : 而是 bb 本身的 name 會被 sdSubsetFun 在裏面識別出來,進而組成一個新的
: : expression 當做 subsetBy 的引數。
: : 不過如果你看不懂
: : x <- 10
: : rm(x) 跟 rm(10) 的這個基本又神秘的地方,那我也不知道該怎麼跟你說明了。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 139.184.222.89
※ 編輯: cog5566 來自: 139.184.222.89 (06/03 00:07)
推
06/03 01:53, , 1F
06/03 01:53, 1F
討論串 (同標題文章)
R_Language 近期熱門文章
PTT數位生活區 即時熱門文章