title: Simple water demand supply model in R
body: <p>I am trying to work out a simple soil water balance in R. Here's the step I need to do:</p>
  
  <p>For a given year, starting from doy 200,I need to determine the Soil Water (SWi) which is calculated by following formula</p>
  
  <pre><code>              `SW(i) = SW(i-1)  + Rain(i) - ETo(i)` 
  </code></pre>
  
  <p>where <code>SW(i-1)</code> is the water content in previous day, <code>Rain(i)</code> is the rainfall and <code>ETo(i)</code> is the evapotranspiration on day i</p>
  
  <p>The conditions are that SW(i) cannot be negative or be more than SW(max) which is 20.</p>
  
  <p>Here's a sample data: </p>
  
  <pre><code>        library(tidyverse)
          set.seed(123)
  
          dat &lt;- tibble(
                year = rep(1980:2015, each = 100),
                day = rep(200:299, times = 36),
                rain = sample(0:17, size = 100*36,replace = T),
                eto = sample(2:9, size = 100*36,replace = T))
  
          SW.initial &lt;- data.frame(year= 1980:2015, SW.199 = sample(1:10, 36, replace = T))
  </code></pre>
  
  <p>SW.initial is the water content for doy 199 for for each year </p>
  
  <pre><code>        SW.max &lt;- 20 
          dat$SW.fin &lt;- NA                    
  </code></pre>
  
  <p>Taking the example of year 1980</p>
  
  <pre><code>        dat.1980 &lt;- dat[dat$year == 1980,]
          SW.initial.1980 &lt;- SW.initial[SW.initial$year== 1980,"SW.199"]
  
          for(doy in dat.1980$day){
  
              SW &lt;- SW.initial.1980 
              SW &lt;- SW + dat.1980[dat.1980$day == doy, "rain"] - dat.1980[dat.1980$day == doy, "eto"]
              SW &lt;- ifelse(SW &lt; 0, 0, ifelse(SW &gt;= SW.max, SW.max, SW))
              dat[dat$year == years &amp; dat$day == doy,"SW.fin"] &lt;- SW
              SW.initial.1980 &lt;- SW
            }
  </code></pre>
  
  <p>This loop will give me the SW of each day starting doy 200 till 299 using: </p>
  
  <pre><code>      `SW(i) = SW(i-1) + Rain[i] + ETo[i]`` 
  </code></pre>
  
  <p>where for doy 200, SW(i-1) was given from the <code>SW.initial</code> data frame</p>
  
  <p>I can loop through all years:</p>
  
  <pre><code>        for(years in unique(dat$year)){
                  test &lt;- dat[dat$year == years,]
                  SW.in &lt;- SW.initial[SW.initial$year == years,"SW.199"]
                for(doy in test$day){
                      SW &lt;- SW.in 
                      SW &lt;- SW + test[test$day == doy, "rain"] - test[test$day == doy, "eto"]
                      SW &lt;- ifelse(SW &lt; 0, 0, ifelse(SW &gt;= SW.max, SW.max, SW))
                      dat[dat$year == years &amp; dat$day == doy,"SW.fin"] &lt;- SW
                      SW.in &lt;- SW
            }}
  </code></pre>
  
  <p>I really want to avoid this long loop and was thinking if there is much clever (and faster way to do this).</p>