【问题标题】:How to create multiple loops inside a function in r如何在r中的函数内创建多个循环
【发布时间】:2021-12-21 05:12:42
【问题描述】:

我想为每个步骤获取新值,并在方程式中使用它们以进行进一步的步骤。通常,我可以执行循环,但对于这个问题,我也需要使用过去的值。例如,我有这样的流量数据:

q<-c(10, 15.83333, 21.66667)

我手动创建了一个循环:

    z1<-190 #initial elevation
      s1<-24011 #initial storage
      in1<-q[1] #initial inflow
      out1<-1.86*sqrt((z1-110)*19.62) #outflow
      z2<-  z1+0.3*((in1-out1)/s1) #elevation at second step
      
      in2<-q[2] #second inflow
      out2<-1.86*sqrt((z2-110)*19.62) #outflow at z2 elevation
    ds2<-0.3*((in1+in2)/2-(out1+out2)/2) #change in storage 
     s2<-s1+ds2 #net storage value
     z3<-z2+0.3*((in2-out2)/s2) #elevation at third step
      
     in3<-q[3]
     out3<-1.86*sqrt((z3-110)*19.62)
     ds3<-0.3*((in2+in3)/2-(out2+out3)/2)
     s3<-s2+ds3 
.
.
.
     z4<-z3+0.3*((in3-out3)/s3) 

简而言之,我正在使用 in,out,s 的先前值计算 z 值。我需要找到的是考虑到q 值的z 值。

预期结果是:

        z        q     outflows  storages
[1,] 190.0000 10.00000 73.68981 24011.00
[2,] 189.9992 15.83333 73.68944 23992.77
[3,] 189.9985 21.66667 73.68911 23976.29

【问题讨论】:

  • 只需更新循环内的变量。您可以在第一步启动您的 vars,它们循环 q 覆盖 zq ...etc vars
  • 但是我该如何安排 (ds2

标签: r loops


【解决方案1】:
  1. 初始化值并创建结果表
  2. 将当前状态值添加到表中
  3. 使用旧状态或新状态模拟新状态
  4. 为所有变量设置新状态
library(tidyverse)

data <- tibble(step = numeric(), out = numeric(), y = numeric(), z = numeric())

# Initialization
z <- 190
y <- 1
out <- NA

for (step in seq(5)) {
  # save current state
  data <- data %>% add_row(step = step, out = out, z = z, y = y)

  # use old state of z
  new_out <- z / 2
  
  # use old state of y
  new_z <- y + 1 
  
  # use new state of out
  new_y <- new_out
  
  # Lastly, update all new variables
  out <- new_out
  y <- new_y
  z <- new_z
}
data
#> # A tibble: 5 x 4
#>    step   out     y     z
#>   <dbl> <dbl> <dbl> <dbl>
#> 1     1    NA     1   190
#> 2     2    95    95     2
#> 3     3     1     1    96
#> 4     4    48    48     2
#> 5     5     1     1    49

reprex package (v2.0.1) 于 2021 年 11 月 10 日创建

【讨论】:

  • 我试过这个,但我怎么能调用以前的值呢?例如,对于这个“ds2
  • @HüsamettinTayşi 我修改了我的答案以使用明确的名称,例如 ynew_y。请记住,如果您同时使用来自不同时间点的状态,您就是在弯曲时间......
【解决方案2】:

我将在这里扩展我的评论。

您可以覆盖变量。例如,在您的实施之后,您可以为您的 out2 创建一个时间变量:

q = c(10, 15.83333, 21.66667)

#Results storage array
results = array(numeric(),c(length(q),4)) 
colnames(results) = c("z", "q", "outflows", "storages")

z = 190
s = 24011
infl = q[1]
out = 1.86*sqrt((z-110)*19.62)

#Save init values
results[1,1] = z
results[,2] = q
results[1,3] = out
results[1,4] = s

for (n in 2:length(q)) {

  z = z+0.3*((infl-out)/s)
  out_tmp = 1.86*sqrt((z-110)*19.62)
  ds = 0.3*((infl+q[n])/2-(out+out_tmp)/2)
  s = s+ds
  infl = q[n] 
  out = out_tmp

  results[n,1] = z
  results[n,3] = out
  results[n,4] = s

}

View(results)

如果你想避免创建时间变量,你可以试试这样:

q = c(10, 15.83333, 21.66667)

results = array(numeric(),c(length(q),4)) 
colnames(results) = c("z", "q", "outflows", "storages")
z = 190
s = 24011
infl = q[1]
out = 1.86*sqrt((z-110)*19.62)

#Save init values
results[1,1] = z
results[,2] = q
results[1,3] = out
results[1,4] = s

for (n in 2:length(q)) {

  z = z+0.3*((infl-out)/s)
  out = 1.86*sqrt((z-110)*19.62)
  ds = 0.3*((infl+q[n])/2-(results[n-1,3]+out)/2)
  s = s+ds
  infl = q[n] 

  results[n,1] = z
  results[n,3] = out
  results[n,4] = s

}

查看(结果)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-30
    • 1970-01-01
    • 1970-01-01
    • 2016-04-22
    相关资源
    最近更新 更多