Re: [問題] 不會傳遞 expression 到sub-function

看板R_Language作者 (刃之56)時間11年前 (2013/06/02 11:56), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串3/8 (看更多)
※ 引述《Chris7462 (~烤焦麵包~)》之銘言: : ※ 引述《cog5566 (刃之56)》之銘言: : : [問題類型]: : : 程式諮詢(我想用R 做某件事情,但是我不知道要怎麼用R 寫出來) : : [軟體熟悉度]: : : 入門(寫過其他程式,只是對語法不熟悉) : : [問題敘述]: : : 以 subsetBy 為例好了 (這是doBy package 的一個function) : : 這個 function 可以依照組別來篩選 data frame 的資料。 : : 假設我想要寫一個 function 會用到 subsetBy : : 這個 function 的功能是依組別去除 2 倍 SD 之外的資料 : : 問題如下: : : subsetBy 的第二個參數是要輸入一個 expression (應該是吧) : subsetBy(formula, subset, data = parent.frame(), select, drop=FALSE, : join=TRUE, ... ) : 第二個參數是 logical 不是 expression,可以看他的說明 : subset logical expression indicating elements or rows to keep: missing values : taken as false. : 用他的 example 看一下就知道了 : sbstBy> data(dietox) : sbstBy> subsetBy(~Evit, Weight < mean(Weight), data=dietox) : data(dietox) : dietox$Weight < mean(dietox$Weight) 我想不是 logical 是 logical expression 你看例子的第二個參數是 Weight < mean(Weight) 並不是 dietox$Weight < mean(dietox$Weight) 如果你用 typeof(Weight < mean(Weight)) 和 typeof(dietox$Weight < mean(dietox$Weight)) 會得到完全不一樣的結果 Weight < mean(Weight) 會變成 logical class 會是在 subsetBy 自己的 scope 之內 的事,但是在 subsetBy 之外的時候狀況很奇怪。 這也是一個我很不習慣 R 的地方之一。有一些 function 會展現出奇怪的特性, 就是你不知道到底 function 是抓引數的 value 還是 name or expression 譬如說好了 x <- 10 rm('x') 和 rm(x) 有同樣的效果 看起來好像沒有很奇怪,但是爲什麽 rm(x) 不會變成 rm(10)呢? 下面這個例子就會更奇怪 x <- 10 y <- 'x' rm(y) 那到底這個時候是什麽情況,到底這時候會抓 rm 的參數 name y 還是 value 'x'? 回到我的問題的例子 subsetBy(~Evit, Weight < mean(Weight), data=dietox) 如果在一般的 function下,而且 Weight 有給予值時, Weight < mean(Weight) 應該會去抓 Weight 的值來得出 logical class 但是這邊等神奇之處就是,Weight 是 dietox 的一個 column, 或是複雜一點的說,是 dietox 這個 data frame 的 environment 裏面的變數 他們是在 subsetBy 之內才被組合的。 這樣一來,subsetBy 必定會知道 subsetBy 外面被 call 時引數的 expression 而不是值。現在知道這可以用 substitute 來實現,但是我的問題是如果有下一層, 如何將這個 expression 帶到下一層? : : 如 : : subsetBy(~Evit, Weight < mean(Weight), data=dietox) : : 這個 expression 是篩選資料的算式,其中的變數會對應到 data frame : : 的 column name : : 而我想要寫一個 function 是 : : sdSubsetFun = function(group, dVar, data) : : data 是我要操作的 data frame : : dVar 是要去掉的 2SD 的目標 column name : : group 是分組的依據 (class 是 formula) : : 但是我沒辦法將 dVar 傳進去裏面的 subsetBy 的第二個參數 : : 程式碼如下 : : ###################################################################### : : 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))) ) : + subsetThreshold = (dVar > (mean(dVar) - 2*sd(dVar))) & : + (dVar < (mean(dVar) + 2*sd(dVar))) : : dataOut = subsetBy(group, : : - subset = eval(subsetThreshold, group, parent.frame()), : + subset = subsetThreshold, : : data = data) : : } : - 是刪除,+ 是新增。這樣應該就可以用了 :p 我還是會不行用耶,貼上我的 code ###################################################################### library('doBy') sdSubsetFun = function(group, dVar, data) { # 2SD threshold subsetThreshold = (dVar > (mean(dVar) - 2*sd(dVar))) & (dVar < (mean(dVar) + 2*sd(dVar))) dataOut = subsetBy(group, subset = subsetThreshold, data = data) } x = rep(c('a','b','c'), 50) y = 1:150 tData = data.frame(aa = x, bb = y) subData = sdSubsetFun(~aa, bb, tData) ###################################################################### Error in sdSubsetFun(~aa, bb, tData) : object 'bb' not found ###################################################################### 其實很顯而易見,在 evaluate dVar 的時候會在 local environment 找不到值, 因為 dynamic scope 的關係,它會去 global environment 找,但也會找不到。 所以他會再找 bb 的value,但是根本就沒有 bb 這個變數,bb是tData的 column name 所以最後他會說 bb 找不到。 還是說我什麽地方弄錯了?可能有小細節沒有注意到。 : : # Create Data : : aa = rep(c('a','b','c'), 50) : : bb = 1:150 : : tData = data.frame(aa,bb) : : subData = sdSubsetFun(~aa, bb, tData) : : ###################################################################### : : 錯誤訊息為: : : Error in eval(subsetThreshold, group, parent.frame()) : : : object 'subsetThreshold' not found : : 也就是說,裏面的 subsetBy 都不會抓我的 subsetThreshold 的值, : : 都還是會抓 subsetThreshold 自己本身的 expression。 : : 要怎麼做才會讓他抓到 subsetThreshold 的值呢? -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 139.184.222.89
文章代碼(AID): #1Hgi9SEw (R_Language)
討論串 (同標題文章)
文章代碼(AID): #1Hgi9SEw (R_Language)