通过for循环填充3D矩阵,其值为R

Fab*_*olz 2 3d for-loop r matrix

我建立了一个尺寸为365x7x4的3维矩阵.

x <- array(rep(1, 365*5*4), dim=c(365, 5, 4))
Run Code Online (Sandbox Code Playgroud)

现在我想使用for循环用一个值填充每个元素.让我们说每个元素的值应该是行,列和深度的总和.我想这相对容易.

谢谢!最好的,F

Rei*_*son 7

使用一个更简单的例子,我们可以看到正在做什么

arr <- array(seq_len(3*3*3), dim = rep(3,3,3))
Run Code Online (Sandbox Code Playgroud)

以下代码提供了请求的输出:

dims <- dim(arr)
ind <- expand.grid(lapply(dims, seq_len))
arr[] <- rowSums(ind)
Run Code Online (Sandbox Code Playgroud)

以上给出

> arr
, , 1

     [,1] [,2] [,3]
[1,]    3    4    5
[2,]    4    5    6
[3,]    5    6    7

, , 2

     [,1] [,2] [,3]
[1,]    4    5    6
[2,]    5    6    7
[3,]    6    7    8

, , 3

     [,1] [,2] [,3]
[1,]    5    6    7
[2,]    6    7    8
[3,]    7    8    9

> arr[1,1,1]
[1] 3
> arr[1,2,3]
[1] 6
> arr[3,3,3]
[1] 9
Run Code Online (Sandbox Code Playgroud)

更新:使用@TimP的答案在这里我更新答案,以显示如何以更像R的方式完成它.

特定

arr <- array(seq_len(3*3*3), dim = rep(3,3,3))
Run Code Online (Sandbox Code Playgroud)

替换arrwith的元素,i + j + k除非k > 2在这种情况下j*k-i使用.

dims <- dim(arr)
ind <- expand.grid(lapply(dims, seq_len))
## which k > 2
want <- ind[,3] > 2
arr[!want] <- rowSums(ind[!want, ])
arr[want] <- ind[want, 2] * ind[want, 3] - ind[want, 1]
Run Code Online (Sandbox Code Playgroud)

虽然很容易坚持使用像循环这样熟悉的习语,但与流行的观念相反,R在R 中并不低效,学习以矢量化方式思考会在学习语言并开始将其应用于数据分析任务时多付出代价.

以下是Fabian的一些例子:

> x <- array(rep(1, 365*5*4), dim=c(365, 5, 4))
> system.time({
+ for (i in seq_len(dim(x)[1])) {
+     for (j in seq_len(dim(x)[2])) {
+         for (k in seq_len(dim(x)[3])) {
+             val = i+j+k
+             if (k > 2) {
+                 val = j*k-i
+             }
+             x[i,j,k] = val
+         }
+     }
+ }
+ })
   user  system elapsed 
  0.043   0.000   0.044 
> arr <- array(rep(1, 365*5*4), dim=c(365, 5, 4))
> system.time({
+ dims <- dim(arr)
+ ind <- expand.grid(lapply(dims, seq_len))
+ ## which k > 2
+ want <- ind[,3] > 2
+ arr[!want] <- rowSums(ind[!want, ])
+ arr[want] <- ind[want, 2] * ind[want, 3] - ind[want, 1]
+ })
   user  system elapsed 
  0.005   0.000   0.006
Run Code Online (Sandbox Code Playgroud)

并为更大(至少我的ickle笔记本电脑!)问题

> x <- array(rep(1, 200*200*200), dim=c(200, 200, 200))
> system.time({
+ for (i in seq_len(dim(x)[1])) {
+     for (j in seq_len(dim(x)[2])) {
+         for (k in seq_len(dim(x)[3])) {
+             val = i+j+k
+             if (k > 2) {
+                 val = j*k-i
+             }
+             x[i,j,k] = val
+         }
+     }
+ }
+ })
   user  system elapsed 
 51.759   0.129  53.090
> arr <- array(rep(1, 200*200*200), dim=c(200, 200, 200))
> system.time({
+     dims <- dim(arr)
+     ind <- expand.grid(lapply(dims, seq_len))
+     ## which k > 2
+     want <- ind[,3] > 2
+     arr[!want] <- rowSums(ind[!want, ])
+     arr[want] <- ind[want, 2] * ind[want, 3] - ind[want, 1]
+ })
   user  system elapsed 
  2.282   1.036   3.397 
Run Code Online (Sandbox Code Playgroud)

但即便如此,按今天的标准来说,这可能是适度的.您可以看到,由于该方法所需的所有函数调用,循环开始变得更加缺乏竞争力.