[英]How to use acast (reshape2) within a function in R?
我试图用acast
从reshape2
自写的函数中,但有这样的acast没有找到我发送给它的数据的问题。
这是我的数据:
library("reshape2")
x <- data.frame(1:3, rnorm(3), rnorm(3), rnorm(3))
colnames(x) <- c("id", "var1", "var2", "var3")
y <-melt(x, id = "id", measure = c("var1", "var2", "var3"))
y
则是这样的:
id variable value
1 1 var1 0.1560812
2 2 var1 1.0343844
3 3 var1 -1.4157728
4 1 var2 0.8808935
5 2 var2 0.1719239
6 3 var2 0.6723758
7 1 var3 -0.7589631
8 2 var3 1.1325995
9 3 var3 -1.5744876
现在我可以通过acast
把它acast
回来:
> acast(y,y[,1] ~ y[,2])
var1 var2 var3
1 0.1560812 0.8808935 -0.7589631
2 1.0343844 0.1719239 1.1325995
3 -1.4157728 0.6723758 -1.5744876
但是,当为一个应该做同样的acast
编写一个小包装器时,我得到一个愚蠢的错误消息:
wrap.acast <- function(dat, v1 = 1, v2 = 2) {
out <- acast(dat, dat[,v1] ~ dat[,v2])
return(out)
}
wrap.acast(y)
Error in eval(expr, envir, enclos) : object 'dat' not found
问题显然与环境和全局/局部变量有关。 因为它在全局环境中声明dat
之后给出了其他错误消息(即,只要它们不是全局的,就找不到v1
和v2
)。
我想在函数中使用resahpe(特别是acast)而不必在函数外声明变量。 诀窍是什么?
谢谢。
而不是使用公式规范,使用字符规范:
acast(y, list(names(y)[1], names(y)[2]))
一个问题是你在R中滥用公式表示法。你不应该这样做
> acast(y, y[,1] ~ y[,2])
var1 var2 var3
1 2.1726117 0.6107264 0.291446236
2 0.4755095 -0.9340976 -0.443291873
3 -0.7099464 -1.2536334 0.001105352
因为如果提供数据对象,'y'位是多余的。 如果你直接在公式中引用y的变量,那么事情很有效
> acast(y, id ~ variable)
var1 var2 var3
1 2.1726117 0.6107264 0.291446236
2 0.4755095 -0.9340976 -0.443291873
3 -0.7099464 -1.2536334 0.001105352
并且在第二个版本中代码更具可读性。
使用acast
包装器做你想做的事情将涉及使用names
生成正确的公式,正如Joris所指出的那样,Hadley的解决方案要简单得多。 所以我的观点是要注意你如何在R中使用公式规范。如果正确使用公式,从长远来看,你会省去很多麻烦(虽然不是特别针对这个特殊问题)。
更正:问题不在于它没有找到dat,而是在指定的公式中找不到dat [,v1]和dat [,v2]。 Acast接受类型公式的参数,并在围绕数据框创建的临时环境中对其进行评估。 在该环境中,当函数包含在另一个函数中时,它不会找到“dat”对象。
我并没有完全关注它在全局中是如何工作的,并且在包装时没有,但如果你给acast一个公式,它也可以在函数中工作。
wrap.acast <- function(dat, v1 = 1, v2 = 2) {
x1 <- names(dat)[v1]
x2 <- names(dat)[v2]
form <- as.formula(paste(x1,"~",x2))
out <- acast(dat,form)
return(out)
}
使用您的玩具数据:
> wrap.acast(y)
var1 var2 var3
1 0.04095337 0.4044572 -0.4532233
2 1.23905358 1.2493187 0.7083557
3 0.72798307 0.7868746 1.7144811
我找到了一种使用超级赋值( <<-
)来解决问题的非常不优雅的方法。
将功能更改为以下功能。 但是,它是非常难看的,因为它创造了仍然存在的全局变量。
wrap.acast <- function(dat, v1 = 1, v2 = 2) {
dat <<- dat
v1 <<- v1
v2 <<- v2
out <- acast(dat, dat[,v1] ~ dat[,v2])
return(out)
}
我对其他(堵塞较少)解决方案仍然很感兴趣。
在运行函数之前:
> ls()
[1] "wrap.acast" "x" "y"
运行功能后:
> ls()
[1] "dat" "v1" "v2" "wrap.acast" "x"
[6] "y"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.