使用 R 中的值通过 for 循环填充 3D 矩阵 [英] Filling a 3D Matrix by for loops with values in R

查看:16
本文介绍了使用 R 中的值通过 for 循环填充 3D 矩阵的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我设置了一个大小为 365x7x4 的 3 维矩阵.

I set up a 3 dimensinoal matrix of size 365x7x4.

x <- array(rep(1, 365*5*4), dim=c(365, 5, 4))

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

Now I would to use a for loop to fill each element with a value. Lets say the value of each element should be sum of row, column and depth. I guess this is relatively easy.

谢谢!最好的,F

推荐答案

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

Using a simpler example so we can see what is being done

arr <- array(seq_len(3*3*3), dim = rep(3,3,3))

以下代码给出了请求的输出:

the following code gives the requested output:

dims <- dim(arr)
ind <- expand.grid(lapply(dims, seq_len))
arr[] <- rowSums(ind)

以上给出

> 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

更新:这里使用@TimP 的答案中的示例,我更新了答案,以展示如何以更像 R 的方式完成.

Update: Using the example in @TimP's Answer here I update the Answer to show how it can be done in a more R-like fashion.

给定

arr <- array(seq_len(3*3*3), dim = rep(3,3,3))

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

Replace elements of arr with i + j + k unless k > 2, in which case j*k-i is used instead.

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]

虽然很容易坚持使用循环等熟悉的习语,并且与流行的看法相反,循环在 R 中并非效率低下,但学习以矢量化的方式思考将在学习过程中多次获得回报语言并开始将其应用于数据分析任务.

Whilst it is tempting to stick with familiar idioms like looping, and contrary to popular belief loops are not inefficient in R, learning to think in a vectorised way will pay off many times over as you learn the language and start applying it to data analysis task.

以下是 Fabian 示例中的一些时间:

Here are some timings on Fabian's example:

> 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

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

and for a much larger (for my ickle laptop at least!) problem

> 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 

但即使按照今天的标准,这也可能是适度的.您可以看到循环开始变得越来越没有竞争力,因为该方法需要调用所有函数.

but even that may be modest to small by today's standards. You can see that the looping starts to become ever more uncompetitive because of the all the function calls required by that method.

这篇关于使用 R 中的值通过 for 循环填充 3D 矩阵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆