我喜欢定义一个 data.frame(A,B,C,...) 的 3D 数组,这样我就可以做
for (x in 1:4)
for (y in 1:5)
for (z in 1:5) {
m[x,y,z]$A <- dnorm(1)
m[x,y,z]$B <- dnorm(1)
m[x,y,z]$C <- dnorm(1)
}
如果我得到一个带有 x,y,z id 的 data.frame(x,y,z,A,B,C) 和一个简短而有效的方法来操作和读取任何行"x,y,z",那也没关系。
也许有更好的主意?我喜欢摆脱
mA[x,y,z] <- ...
mB[x,y,z] <- ...
mC[x,y,z] <- ...
更标准的格式是具有 6 列的数据框,--- x、y、z、A、B 和 C。您可以通过以下方式实现此目的:
dat <- expand.grid(x=1:4, y=1:5, z=1:5, A=dnorm(1), B=dnorm(1), C=dnorm(1))
head(dat)
# x y z A B C
# 1 1 1 1 0.2419707 0.2419707 0.2419707
# 2 2 1 1 0.2419707 0.2419707 0.2419707
# 3 3 1 1 0.2419707 0.2419707 0.2419707
# 4 4 1 1 0.2419707 0.2419707 0.2419707
# 5 1 2 1 0.2419707 0.2419707 0.2419707
# 6 2 2 1 0.2419707 0.2419707 0.2419707
我猜你的意思是rnorm
因为用dnorm(1)
填充整个数组似乎不是很有趣。使用以下命令一次性创建数组会快得多:
m <- array( rnorm(4*5*5*3),
dims= c(4,5,5, 3) ,
dimnames=list(x=NULL, y=NULL, z=NULL, lets=c("A","B","C") ) )
因此,从该 4d 数组访问,它将是:
> m[ 1,1,1,"A"]
A
0.6773062520076687
> m[ 1,1,1,"B"]
B
0.6229924684213618
> m[ 1,1,1,"C"]
C
0.6899440670029088
或者,如果您希望将它们三个都作为向量:
> m[ 1,1,1, ]
A B C
0.6773062520076687 0.6229924684213618 0.6899440670029088
其他答案提供了您最初想要做的很好的替代方案。 使用其中之一。
但无论如何,这里有一种方法可以解决原始问题:
m_dims <- c(4, 5, 5)
make_data_frame <- function(i) {
data.frame(A = dnorm(1), B = dnorm(2), C = dnorm(3))
}
m <- lapply(seq_len(prod(m_dims)), make_data_frame)
m <- array(m, m_dims)
请注意,您需要双括号才能访问此野兽:
m[[1, 1, 1]]$A
玩弄(并犯错误)是更熟悉 R 如何实现列表、矩阵和数据帧的好方法。但我不能说我会推荐它。
我认为这里的其他两个答案几乎肯定是你想要的。但出于兴趣,您可以制作一个 data.frame 的三维列表:
a <- data.frame(x = rnorm(2700), y = rnorm(2700), z = rnorm(2700))
b <- plyr::alply(expand.grid(A = 0:2, B = 0:2, C = 0:2), 1, function(x) with(x, a[9 * C + 3 * B + A + 1:100, ]))
dim(b) <- rep(3, 3)
b[[1, 2, 3]]$x