我一直在尝试更多地了解R中的环境。通过阅读,似乎我应该能够使用with()和transform()等函数来修改data.frame中的变量,就好像我在该对象的环境中运行。所以,我认为以下内容可能有效:
X <- expand.grid(
Cond=c("baseline","perceptual","semantic"),
Age=c("child","adult"),
Gender=c("male","female")
)
Z <- transform(X,
contrasts(Cond) <- cbind(c(1,0,-1)/2, c(1,-2,1))/4,
contrasts(Age) <- cbind(c(-1,1)/2),
contrasts(Gender) <- cbind(c(-1,1)/2)
)
str(Z)
contrasts(Z$Cond)
但事实并非如此。我希望有人可以解释原因。当然,我理解contrasts(X$Cond) <- ...
会起作用,但我很好奇为什么不这样做。
事实上,这也不起作用[编辑:假,这确实有效。我在最初发布之前快速尝试了这个并做错了一些事情]:
attach(X)
contrasts(Cond) <- cbind(c(1,0,-1)/2, c(1,-2,1))/4
contrasts(Age) <- cbind(c(-1,1)/2)
contrasts(Gender) <- cbind(c(-1,1)/2)
detach(X)
如果这是一个&#34; RTFM&#34;我很抱歉有点事......不是我看不到的。我只是不明白。谢谢!
[编辑:谢谢你joran --- in()而不是with()或transform()就可以了!以下语法有效。]
Z <- within(X, {
contrasts(Cond) <- ...
contrasts(Age) <- ...
contrasts(Gender) <- ...
}
)
答案 0 :(得分:3)
transform
绝对是错误的工具。并且您不希望with
,您可能需要within
,以便返回整个对象:
X <- within(X,{contrasts(Cond) <- cbind(c(1,0,-1)/2, c(1,-2,1))/4
contrasts(Age) <- cbind(c(-1,1)/2)
contrasts(Gender) <- cbind(c(-1,1)/2)})
这里唯一棘手的部分是记住花括号以在一个表达式中包含多行。
你的最后一个例子,使用attach
,对我来说效果很好。
transform
仅用于计算tag = value
形式的表达式,并且由于它评估这些表达式的方式,它实际上并未设置为修改列的属性。它更适用于对列本身的直接修改。 (缩放,记录日志等)
with
的价值部分很好地总结了within
和?within
之间的差异:
值对于with,计算的expr的值。对于内部,修改后的对象。
所以with
只返回表达式的结果。 within
用于修改对象并返回整个对象。
答案 1 :(得分:1)
虽然我同意@Jornan within
这里是最好的策略,但我会指出可以使用transform
你需要以不同的方式这样做
Z <- transform(X,
Cond = `contrasts<-`(Cond, value=cbind(c(1,0,-1)/2, c(1,-2,1))/4),
Age = `contrasts<-`(Age, value=cbind(c(-1,1)/2)),
Gender= `contrasts<-`(Gender, value=cbind(c(-1,1)/2))
)
这里我们显式调用运行contrasts(a)=b
时使用的魔术函数。这实际上返回的值可以与a=b
期望的transform
格式一起使用。当然它会使X
保持不变。
within
解决方案当然看起来更干净。