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

看板R_Language作者 (刃之56)時間11年前 (2013/06/03 00:02), 編輯推噓1(100)
留言1則, 1人參與, 最新討論串7/8 (看更多)
感謝版主的回應。 我也是在看 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
文章代碼(AID): #1HgsoT73 (R_Language)
討論串 (同標題文章)
文章代碼(AID): #1HgsoT73 (R_Language)