项目 R:for 循环的变量 "depth";概括
Project R: Variable "depth" of for-loops; generalization
谢谢你帮我解决这个问题。这是一个困扰我很久的问题。我觉得我离答案很近了,但还没有完全到那儿。
问题如下:
假设我想组合 n 个向量的 m 个元素的所有可能组合,并存储比方说乘法的结果。对于二维问题,我需要两个交错的 for 循环:
dim2_Matrix <- matrix(0,nrow=2,ncol=3)
for (i in 1:2){
for (j in 1:3){
dim2_Matrix[i,j] <- i*j
}
}
内循环将 运行 遍历所有 3 项,将它们与外循环的第一项相乘。一旦该过程完成,我将增加并且内部循环再次从 j=1 开始。我们有 2*3 = 6 种组合。
现在让我们将其提升为 3D 问题。我们需要第三个循环:
dim3_Matrix <- array(0,dim=c(2,3,4))
for (i in 1:2){
for (j in 1:3){
for (k in 1:4){
dim3_Matrix[i,j,k] <- i*j*k
}
}
}
它运行是最内循环4次,增加中间循环,运行再次是4个内循环...直到我们得到2*3*4 = 24个组合3D 数组。
我可以继续使用 dim4、dim5 等。
我现在的问题是我想保留脚本变量。有时我想组合 2 个,有时是 3 个,有时是 n 个向量。假设我知道在循环 运行 之前有多少 "layers" ...我如何得到这个的一般形式?
我是这样的:
n_dimensions <- 3 # specify n° of dimensions
m_Elements <- c(2,3,4) # 2 elements in 1st dim, 3 in 2nd, 4 in 3rd
for (i in 1:n_dimensions){
for (j in 1:m_Elements[i]){
# ...
}
}
但这会是这样的:
i1 j1 --> i1 j2
i2 j1 --> i2 j2 --> i2 j3
i3 j1 --> i3 j2 --> i3 j3 --> i3 j4
所以这是 2 + 3 + 4 组合而不是 2*3*4。
请注意:乘法只是一个例子。将结果存储在 matrix/tensor 中并不是主要问题。这是如何交织循环并概括它。
感谢您通读,希望您明白我的意思!
你可以尝试这样的事情。
X<-list(1:2, 1:3, 1:4) #one entry for each dimension
Z<-expand.grid(X)
Z 看起来像:
Var1 Var2 Var3
1 1 1 1
2 2 1 1
3 1 2 1
4 2 2 1
5 1 3 1
6 2 3 1
7 1 1 2
8 2 1 2
9 1 2 2
10 2 2 2
11 1 3 2
12 2 3 2
13 1 1 3
14 2 1 3
15 1 2 3
16 2 2 3
17 1 3 3
18 2 3 3
19 1 1 4
20 2 1 4
21 1 2 4
22 2 2 4
23 1 3 4
24 2 3 4
所以现在您在 data.frame
中拥有所有组合,您可以使用应用函数或类似的东西来完成您需要做的事情。如:
apply(Z,1,prod)
[1] 1 2 2 4 3 6 2 4 4 8 6 12 3 6 6 12 9 18 4 8 8 16 12 24
您的代码相当于:
dim2_Matrix = outer(1:2, 1:3)
dim3_Matrix = outer(dim2_Matrix, 1:4)
可以概括为:
dim_n_Matrix <- function(n) {
x <- 1:2
if (n>1) {for (n in 2:n) {x <- outer(x, 1:(n+1))}} else {x <- matrix(1:2, nrow = 1)}
return(x)
}
谢谢你帮我解决这个问题。这是一个困扰我很久的问题。我觉得我离答案很近了,但还没有完全到那儿。 问题如下:
假设我想组合 n 个向量的 m 个元素的所有可能组合,并存储比方说乘法的结果。对于二维问题,我需要两个交错的 for 循环:
dim2_Matrix <- matrix(0,nrow=2,ncol=3)
for (i in 1:2){
for (j in 1:3){
dim2_Matrix[i,j] <- i*j
}
}
内循环将 运行 遍历所有 3 项,将它们与外循环的第一项相乘。一旦该过程完成,我将增加并且内部循环再次从 j=1 开始。我们有 2*3 = 6 种组合。
现在让我们将其提升为 3D 问题。我们需要第三个循环:
dim3_Matrix <- array(0,dim=c(2,3,4))
for (i in 1:2){
for (j in 1:3){
for (k in 1:4){
dim3_Matrix[i,j,k] <- i*j*k
}
}
}
它运行是最内循环4次,增加中间循环,运行再次是4个内循环...直到我们得到2*3*4 = 24个组合3D 数组。
我可以继续使用 dim4、dim5 等。 我现在的问题是我想保留脚本变量。有时我想组合 2 个,有时是 3 个,有时是 n 个向量。假设我知道在循环 运行 之前有多少 "layers" ...我如何得到这个的一般形式?
我是这样的:
n_dimensions <- 3 # specify n° of dimensions
m_Elements <- c(2,3,4) # 2 elements in 1st dim, 3 in 2nd, 4 in 3rd
for (i in 1:n_dimensions){
for (j in 1:m_Elements[i]){
# ...
}
}
但这会是这样的:
i1 j1 --> i1 j2
i2 j1 --> i2 j2 --> i2 j3
i3 j1 --> i3 j2 --> i3 j3 --> i3 j4
所以这是 2 + 3 + 4 组合而不是 2*3*4。
请注意:乘法只是一个例子。将结果存储在 matrix/tensor 中并不是主要问题。这是如何交织循环并概括它。
感谢您通读,希望您明白我的意思!
你可以尝试这样的事情。
X<-list(1:2, 1:3, 1:4) #one entry for each dimension
Z<-expand.grid(X)
Z 看起来像:
Var1 Var2 Var3
1 1 1 1
2 2 1 1
3 1 2 1
4 2 2 1
5 1 3 1
6 2 3 1
7 1 1 2
8 2 1 2
9 1 2 2
10 2 2 2
11 1 3 2
12 2 3 2
13 1 1 3
14 2 1 3
15 1 2 3
16 2 2 3
17 1 3 3
18 2 3 3
19 1 1 4
20 2 1 4
21 1 2 4
22 2 2 4
23 1 3 4
24 2 3 4
所以现在您在 data.frame
中拥有所有组合,您可以使用应用函数或类似的东西来完成您需要做的事情。如:
apply(Z,1,prod)
[1] 1 2 2 4 3 6 2 4 4 8 6 12 3 6 6 12 9 18 4 8 8 16 12 24
您的代码相当于:
dim2_Matrix = outer(1:2, 1:3)
dim3_Matrix = outer(dim2_Matrix, 1:4)
可以概括为:
dim_n_Matrix <- function(n) {
x <- 1:2
if (n>1) {for (n in 2:n) {x <- outer(x, 1:(n+1))}} else {x <- matrix(1:2, nrow = 1)}
return(x)
}