Finding dimensional index in a multi-dimensional array in R

时间:2021-09-24 19:35:08

Am looking at say 3-dimensional array M: M<-dim(3,3,3)

我在看三维数组M:M <-dim(3,3,3)

I want to find an efficient way to populate M with the following rule: M[i,j,k] = i/10 + j^2 + sqrt(k), ideally without having to write a loop with a for statemenet.

我想找到一种使用以下规则填充M的有效方法:M [i,j,k] = i / 10 + j ^ 2 + sqrt(k),理想情况下无需使用for statemenet编写循环。

For clarification, there is a simple way to accomplishing this if M were 2-dimensional. If i wanted to have M[i,j] = i/10 + j^2, then i could just do M<-row(M)/10 + col(M)*col(M)

为了澄清,如果M是二维的,有一种简单的方法可以实现这一点。如果我想要M [i,j] = i / 10 + j ^ 2,那么我可以做M <-row(M)/ 10 + col(M)* col(M)

Is there something equivalent for 3-or-higher dimensional arrays?

有没有相当于3维或更高维数组的东西?

4 个解决方案

#1


7  

@James's answer is better, but I think the narrow answer to your question (multidimensional equivalent of row()/col()) is slice.index ...

@James的答案更好,但我认为你的问题(多维等效的row()/ col())的狭隘答案是slice.index ...

M<- array(dim=c(3,3,3))
slice.index(M,1)/10+slice.index(M,2)^2+sqrt(slice.index(M,3))

It would be a good idea if someone (I or someone else) posted a suggestion on the r-devel list to make slice.index a "See also" entry on ?row/?col ...

如果有人(我或其他人)在r-devel列表上发布了一条建议,以使slice.index在“row /?col”上显示“另请参阅”条目,那将是个好主意。

Alternatively (similar to @flodel's new answer):

或者(类似于@ flodel的新答案):

d <- do.call(expand.grid,lapply(dim(M),seq)) ## create data.frame of indices
v <- with(d,Var1/10+Var2^2+sqrt(Var3))       ## default names Var1, ... Varn 
dim(v) <- dim(M)                             ## reshape into array

#2


4  

How about using nested outers?

如何使用嵌套的outers?

outer(1:3/10,outer((1:3)^2,sqrt(1:3),"+"),"+")
, , 1

     [,1] [,2] [,3]
[1,]  2.1  5.1 10.1
[2,]  2.2  5.2 10.2
[3,]  2.3  5.3 10.3

, , 2

         [,1]     [,2]     [,3]
[1,] 2.514214 5.514214 10.51421
[2,] 2.614214 5.614214 10.61421
[3,] 2.714214 5.714214 10.71421

, , 3

         [,1]     [,2]     [,3]
[1,] 2.832051 5.832051 10.83205
[2,] 2.932051 5.932051 10.93205
[3,] 3.032051 6.032051 11.03205

#3


2  

You can also use arrayInd:

你也可以使用arrayInd:

M   <- array(dim = c(3, 3, 3))
foo <- function(dim1, dim2, dim3) dim1/10 + dim2^2 + sqrt(dim3)
idx <- arrayInd(seq_along(M), dim(M), useNames = TRUE)
M[] <- do.call(foo, as.data.frame(idx))

I feel this approach has potential for less typing as the number of dimensions increases.

我觉得随着尺寸数量的增加,这种方法有可能减少打字。

#4


1  

Doing it from the "ground up" so to speak.

可以这么说从“地面”做起。

 i <- rep(1:3, times=3*3)
 j <- rep(1:3 , times= 3, each=3)
 k <- rep(1:3 , each= 3*3)
 M <- array( i/10 + j^2 + sqrt(k), c(3, 3, 3))
 M

#1


7  

@James's answer is better, but I think the narrow answer to your question (multidimensional equivalent of row()/col()) is slice.index ...

@James的答案更好,但我认为你的问题(多维等效的row()/ col())的狭隘答案是slice.index ...

M<- array(dim=c(3,3,3))
slice.index(M,1)/10+slice.index(M,2)^2+sqrt(slice.index(M,3))

It would be a good idea if someone (I or someone else) posted a suggestion on the r-devel list to make slice.index a "See also" entry on ?row/?col ...

如果有人(我或其他人)在r-devel列表上发布了一条建议,以使slice.index在“row /?col”上显示“另请参阅”条目,那将是个好主意。

Alternatively (similar to @flodel's new answer):

或者(类似于@ flodel的新答案):

d <- do.call(expand.grid,lapply(dim(M),seq)) ## create data.frame of indices
v <- with(d,Var1/10+Var2^2+sqrt(Var3))       ## default names Var1, ... Varn 
dim(v) <- dim(M)                             ## reshape into array

#2


4  

How about using nested outers?

如何使用嵌套的outers?

outer(1:3/10,outer((1:3)^2,sqrt(1:3),"+"),"+")
, , 1

     [,1] [,2] [,3]
[1,]  2.1  5.1 10.1
[2,]  2.2  5.2 10.2
[3,]  2.3  5.3 10.3

, , 2

         [,1]     [,2]     [,3]
[1,] 2.514214 5.514214 10.51421
[2,] 2.614214 5.614214 10.61421
[3,] 2.714214 5.714214 10.71421

, , 3

         [,1]     [,2]     [,3]
[1,] 2.832051 5.832051 10.83205
[2,] 2.932051 5.932051 10.93205
[3,] 3.032051 6.032051 11.03205

#3


2  

You can also use arrayInd:

你也可以使用arrayInd:

M   <- array(dim = c(3, 3, 3))
foo <- function(dim1, dim2, dim3) dim1/10 + dim2^2 + sqrt(dim3)
idx <- arrayInd(seq_along(M), dim(M), useNames = TRUE)
M[] <- do.call(foo, as.data.frame(idx))

I feel this approach has potential for less typing as the number of dimensions increases.

我觉得随着尺寸数量的增加,这种方法有可能减少打字。

#4


1  

Doing it from the "ground up" so to speak.

可以这么说从“地面”做起。

 i <- rep(1:3, times=3*3)
 j <- rep(1:3 , times= 3, each=3)
 k <- rep(1:3 , each= 3*3)
 M <- array( i/10 + j^2 + sqrt(k), c(3, 3, 3))
 M