title: Building data frame of flood metric calculations with a for loop in R
body: <p>I have a dataset called all.cols2 with water depths taken every 20 minutes for 94 locations over 3+ years. Here is a preview:</p>
  <pre><code> # A tibble: 89,714 x 95
     date_time           Levee.slope      Levee.slope.1      Levee.slope.2    Levee.slope.3
     &lt;dttm&gt;                         &lt;dbl&gt;            &lt;dbl&gt;            &lt;dbl&gt;            &lt;dbl&gt;
   1 2015-12-01 15:05:33           -0.821           -0.539           -0.325          -0.0991
   2 2015-12-01 15:25:33           -0.830           -0.548           -0.334          -0.108 
   3 2015-12-01 15:45:33           -0.829           -0.547           -0.333          -0.107 
   4 2015-12-01 16:05:33           -0.833           -0.551           -0.337          -0.111 
   5 2015-12-01 16:25:33           -0.829           -0.547           -0.333          -0.107 
   6 2015-12-01 16:45:33           -0.834           -0.552           -0.338          -0.112 
   7 2015-12-01 17:05:33           -0.839           -0.557           -0.343          -0.117 
   8 2015-12-01 17:25:33           -0.835           -0.553           -0.339          -0.113 
   9 2015-12-01 17:45:33           -0.826           -0.544           -0.330          -0.104 
  10 2015-12-01 18:05:33           -0.804           -0.522           -0.308          -0.0821
  # ... with 89,704 more rows, and 90 more variables: Levee.slope.4 &lt;dbl&gt;,
  </code></pre>
  <p>I am calculating metrics for individual flooding events at each location.</p>
  <p>Right now I have been using the for loop below to calculate these metrics one location at a time, exporting the results and copying and pasting them into an excel file, which takes a long time. Here is the code I've been using:</p>
  <pre><code>for (col in 1:length(list.sites)))
    #Label and subset by site  
    site &lt;-  paste0(&quot;WaterLevel_&quot;,noquote(list.sites[[1]][i])) 
    mut_sub &lt;- all.cols2 %&gt;% select(&quot;Date&quot;,all_of(site))
    
    # creates binary for positive/negative water level values 
    mut_sub$VarA &lt;- as.integer(mut_sub[,2] &gt; 0) 
    
    # This code is used to label flood events with unique streak_id
    mut_sub &lt;- mut_sub %&gt;% mutate(lagged = lag(VarA))
    mut_sub&lt;-  mut_sub%&gt;% mutate(start = (VarA != lagged)) 
    mut_sub[1, &quot;start&quot;] &lt;- FALSE 
    #filter to keep positive water depths (VarA == 1)
    mut_sub &lt;- mut_sub %&gt;% mutate(streak_id = cumsum(start)) %&gt;%
      filter(VarA == 1)
   
    #calculate mean water depth
    ls &lt;- aggregate(mut_sub[,2], by= list(mut_sub$streak_id), FUN = mean, na.rm = TRUE) 
    
    names(ls)[2] &lt;- &quot;avg_water_depth&quot; 
    
    #calculate max water depth
     MAX &lt;- aggregate(mut_sub[,2], by = list(mut_sub$streak_id), FUN = max, na.rm = TRUE)
     
     names(MAX)[2] &lt;- &quot;max_depth&quot;
    
    #getting length (# of observations) of each event
    obs &lt;- aggregate(mut_sub[,2], by = list(mut_sub$streak_id), FUN = length)
    
    names(obs)[2] &lt;- &quot;observations&quot;
    
    #calculating number of days per event (duration)
    obs &lt;- obs %&gt;%
      mutate(duration_days = (((observations-1)*20)/60)/24)
    
    #Time interval: 
    time &lt;- mut_sub %&gt;% group_by(streak_id) %&gt;% summarise(begin = min(date_time), end = max(date_time))
    time &lt;- time %&gt;% rename(Group.1 = streak_id)
    
    #combine data
    results1 &lt;- inner_join(ls, MAX)
    results2 &lt;- inner_join(results1, obs)
    final &lt;- inner_join(results2, time)
  
   #way to label sites
    final$site = paste(site, final$Group.1, sep = &quot;_&quot;)
  }
  
  ###...repeat above for each survey point, export and add manually in excel 
  </code></pre>
  <p>This gives an output that looks like this (this is from one site):</p>
  <pre><code> Group.1 avg_water_depth   max_depth observations duration_days      begin        end                        site
        1     0.025245673 0.033995673            4    0.04166667 2016-02-09 2016-02-09  WaterLevel_Levee.slope.1_1
        3     0.045995673 0.071995673            8    0.09722222 2016-05-06 2016-05-06  WaterLevel_Levee.slope.1_3
        5     0.003995673 0.005995673            2    0.01388889 2016-05-06 2016-05-06  WaterLevel_Levee.slope.1_5
        7     0.039370673 0.061995673            8    0.09722222 2016-05-07 2016-05-07  WaterLevel_Levee.slope.1_7
        9     0.038785147 0.069995673           19    0.25000000 2016-05-27 2016-05-27  WaterLevel_Levee.slope.1_9
       11     0.063817102 0.110995673           28    0.37500000 2016-05-27 2016-05-28 WaterLevel_Levee.slope.1_11
       13     0.062817102 0.112995673           28    0.37500000 2016-05-28 2016-05-28 WaterLevel_Levee.slope.1_13
       15     0.042495673 0.067995673           18    0.23611111 2016-05-28 2016-05-28 WaterLevel_Levee.slope.1_15
    
  </code></pre>
  <p>...where each flood event at each location has an average water depth, maximum water depth, # of observations, duration in days of the flood event, and the date/time it started and ended.</p>
  <p>Right now I have to specify <code>i</code> before I run the for loop, it doesn't automatically go through my sites.</p>
  <p>My question is, is there a way have to for loop run through all locations at once and store it in a combined output similar to the above table? Also, is there a way to condense the code that I do have in my loop so I don't have to create so many dataframes?</p>