将嵌套的for循环存储到R中的单个向量中

Storing a nested for loop into a single vector in R

假设我有以下代码

b = 1:3
m = 5

for(j in 1:2){
  for(i in 1:5){
    print((1-i/m)* b[j] + (i/m)* b[j+1])
  }
}

如果我打印这个我得到以下输出

[1] 1.2
[1] 1.4
[1] 1.6
[1] 1.8
[1] 2
[1] 2.2
[1] 2.4
[1] 2.6
[1] 2.8
[1] 3

但是,现在我想将此数据存储到单个列向量中。 当我将 print 替换为空向量或列表 z[i] <- 这当然不起作用。 有谁知道如何将 for 循环值放入单个列向量中?

我们可以启动一个向量并将输出附加到它

out <- c()
 for(j in 1:2){
  for(i in 1:5){
    out <- c(out, (1-i/m)* b[j] + (i/m)* b[j+1])
  }
}

df1 <- data.frame(out)

-输出

df1
   out
1  1.2
2  1.4
3  1.6
4  1.8
5  2.0
6  2.2
7  2.4
8  2.6
9  2.8
10 3.0

或者另一个选项是 outer 来自 base R

out <- c(t( outer(1:2, 1:5, FUN = function(j, i) (1-i/m)* b[j] + (i/m)* b[j+1])))

-输出

out
#[1] 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0

或使用expand.grid (R 4.1.0)

expand.grid(j = 1:2, i = 1:5) |> 
      transform(out = (1-i/m)*b[j] + (i/m) * b[j + 1]) |> 
      subset(select = out)
   out
1  1.2
2  2.2
3  1.4
4  2.4
5  1.6
6  2.6
7  1.8
8  2.8
9  2.0
10 3.0

基准


j1 <- 1:200
i1 <- 1:500
# // outer 
system.time({
 out <- c(t( outer(j1, i1, FUN = function(j, i) (1-i/m)* b[j] + (i/m)* b[j+1])))

})
#  user  system elapsed 
#  0.004   0.000   0.004 

# // sapply

system.time({
out2 <- sapply(j1,function(j){
  sapply(i1,function(i){
    out <- (1-i/m)* b[j] + (i/m)* b[j+1]
    return(out)
  })
})
})
# user  system elapsed 
#  0.152   0.004   0.155 

基础R,应用

b = 1:3
m = 5

df <- sapply(1:2,function(j){
  sapply(1:5,function(i){
    out <- (1-i/m)* b[j] + (i/m)* b[j+1]
    return(out)
  })
})

result <- c(df[c(1:5),c(1:2)]) 

结果

[1] 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0

速度测试 - sapply 与 for 循环

b = 1:10001
m = 5

> system.time({ 
+ df <- sapply(1:10000,function(j){
+   sapply(1:5,function(i){
+     out <- (1-i/m)* b[j] + (i/m)* b[j+1]
+     return(out)
+   })
+ })
+ })
   user  system elapsed 
   0.19    0.00    0.19 
 
> system.time({ 
+ out <- c()
+ for(j in 1:10000){
+   for(i in 1:5){
+     out <- c(out, (1-i/m)* b[j] + (i/m)* b[j+1])
+   }
+ }
+ })
   user  system elapsed 
   3.00    0.02    3.02