作者Chris7462 (~烤焦面包~)
看板R_Language
标题Re: [问题] 不会传递 expression 到sub-function
时间Sun Jun 2 13:21:02 2013
※ 引述《cog5566 (刃之56)》之铭言:
: ※ 引述《Chris7462 (~烤焦面包~)》之铭言:
: : 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)
你只看到了第二个参数,没看到後面的 data=dietox
subsetBy 括号里面整个的意思是用 dietox 这组资料的 Weight 也就是 dietox$Weight
可以把资料 attach 上去就知道了。
> data(dietox)
> attach(dietox)
> typeof(Weight < mean(Weight))
[1] "logical"
> typeof(dietox$Weight < mean(dietox$Weight))
[1] "logical"
> Weight == dietox$Weight
两个是一样的
: 如果你用
: typeof(Weight < mean(Weight))
: 和
: typeof(dietox$Weight < mean(dietox$Weight))
: 会得到完全不一样的结果
因为你开 R 的时候有读到旧的资料或是 R 的暂存档,没有 attach dietox 这个 data
的话应该不会 Weight 这个 variable
请先把旧的暂存档或旧资料清掉,不然这样讨论下去你只会一直得到很奇怪的结果
: Weight < mean(Weight) 会变成 logical class 会是在 subsetBy 自己的 scope 之内
: 的事,但是在 subsetBy 之外的时候状况很奇怪。
: 这也是一个我很不习惯 R 的地方之一。有一些 function 会展现出奇怪的特性,
: 就是你不知道到底 function 是抓引数的 value 还是 name or expression
: 譬如说好了
: x <- 10
: rm('x') 和 rm(x)
: 有同样的效果
请看 ?rm
rm (..., list = character(), pos = -1,
envir = as.environment(pos), inherits = FALSE)
...
the objects to be removed, as names (unquoted) or character strings (quoted).
里面放的可以是变数名称或是字串,所以 rm('x') 跟 rm(x) 一样
: 看起来好像没有很奇怪,但是爲什麽 rm(x) 不会变成 rm(10)呢?
: 下面这个例子就会更奇怪
: x <- 10
: y <- 'x'
: rm(y)
: 那到底这个时候是什麽情况,到底这时候会抓 rm 的参数 name y 还是 value 'x'?
请把值呼叫出来
> x # x 是变数,数值为 10
[1] 10
> y # y 是变数,数值是字元 "x"
[1] "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 带到下一层?
: 我还是会不行用耶,贴上我的 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)
问题是出在这边,因为 data = data 用的是 data 这个资料的 data$subsetThreshold
但是 data 下并没有 data$subsetThreshold 这个变数,所以就有 error
: }
: x = rep(c('a','b','c'), 50)
: y = 1:150
: tData = data.frame(aa = x, bb = y)
另外这边也错,两个改法。一个是
> tData = data.frame(aa <- x, bb <- y)
或是
> tData = data.frame(aa = x, bb = y)
> 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 找不到。
: 还是说我什麽地方弄错了?可能有小细节没有注意到。
看不懂上面的几个错误跟 dynamic scope 有什麽关系?
整的问题只是呼叫 function 的时候没有把该放的参数放对而已。
我把整个改过的程式贴上来如下,如果再不行我也不知道怎麽帮你了....
library('doBy')
sdSubsetFun = function(group, dVar, data) {
# 2SD threshold
data$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)
aa <- x
bb <- y
subData = sdSubsetFun(~aa, bb, tData)
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 36.229.4.177
1F:→ Chris7462:另外建议 x = rep(c('a','b','c'), 50) 改成 factor 06/02 13:22
2F:→ Chris7462:x <- factor(rep(c('a','b','c'), 50)) 会比较好 06/02 13:22
※ 编辑: Chris7462 来自: 118.165.62.51 (06/03 01:54)