为什么不能在R中使用with()或transform()分配对比度?

时间:2014-05-07 15:21:19

标签: r dataframe

我一直在尝试更多地了解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) <- ...
  }
)

2 个答案:

答案 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解决方案当然看起来更干净。