title: R calculate and add delta of two dataframe cells for each row
body: <p>I have a data frame that looks like this:</p>
  
  <pre><code>   df &lt;- data.frame(
      "Subject" = c("A", "B", "C", "A", "B", "C"),
      "Stage" = c( "pre", "pre", "pre", "post", "post", "post"), 
      "Value" = c(.5, .2, .7, 1, .8, .3)
  )
  </code></pre>
  
  <p>I want to find the delta between <code>pre</code> and <code>post</code> columns for each row, something like:</p>
  
  <pre><code>delta &lt;- df[df$Stage == 'post' &amp; df$Subject == 'A', ] - df[df$Stage == 'pre' &amp; df$Subject == 'B', ]
  </code></pre>
  
  <p>and then add it to its own column of the data frame:</p>
  
  <pre><code>df[["delt"]] &lt;- NA
  df[df$Subject == 'A', ][["delta"]] &lt;- delta
  </code></pre>
  
  <p>The above works, but when I try to do it to all the rows with this method:</p>
  
  <pre><code>subjects &lt;- unique(df$Subjects)
  df[["delt"]] &lt;- NA
  calc_deltas &lt;- function(position) {
     subject &lt;- subjects[position]
     delta &lt;- df[df$Stage == 'post' &amp; df$Subject == subject, ] - df[df$Stage == 'pre' &amp; df$Subject == subject, ]
     df[df$Subject == subject, ][["delta"]]
  }
  lapply(1:length(subjects), calc_deltas)  
  </code></pre>
  
  <p>I expect the results to come out like this:</p>
  
  <pre><code>  Subject Stage Value delta
  1       A   pre   0.5   0.5
  2       B   pre   0.2   0.6
  3       C   pre   0.7   -0.4
  4       A  post   1.0   0.5
  5       B  post   0.8   0.6
  6       C  post   0.3   -0.4
  </code></pre>
  
  <p>But instead they come out like this:</p>
  
  <pre><code>  Subject Stage Value delta
  1       A   pre   0.5   NA
  2       B   pre   0.2   NA
  3       C   pre   0.7   NA
  4       A  post   1.0   NA
  5       B  post   0.8   NA
  6       C  post   0.3   NA
  </code></pre>
  
  <p>The rows remain as NA values. </p>
  
  <p>My problem is complicated by the fact that I want to do that over multiple groups of observations within each row, I want to add the columns dynamically (I want to use the script for sets of data that, while fundamentally the same, have different groups). Here's the function from my script:</p>
  
  <pre><code>find_deltas &lt;- function(pre_post_survey_data, question_groups) {
    output &lt;- pre_post_survey_data
  
    users &lt;- unique(output$username)
  
    calc_deltas &lt;- function (position, name) {
      user &lt;- users[position]
      calc_col_name &lt;- paste0(name, "_mean")
      save_col_name &lt;- paste0(name, "_delta")
  
      output[output$username == user, ][[save_col_name]] &lt;- output[output$Step == 'post' &amp; output$username == user, ][[calc_col_name]] - output[output$Step == 'pre' &amp; output$username == user, ][[calc_col_name]]
      print(output[output$username == user, ][[save_col_name]])
    }
  
    for (name in names(question_groups)) {
      output[[paste0(name, "_delta")]] &lt;- NA
      lapply(1:length(users), calc_deltas, name)  
    }
  
    output[["total_delta"]] &lt;- NA
    lapply(1:length(users), calc_deltas, 'total')  
  
    output
  }
  </code></pre>
  
  <p>The output in this case looks like this right now (the added delta columns are at the far right, the values are all NA, they ought to be calculated values) (this is example data, and doesn't actually add up as it should, refer to above example for that):</p>
  
  <pre><code>+---------+-------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+--------------+--------------+--------------+-------------+---------------+---------------+---------------+-------------+
  | Subject | Stage | qGroupA.1 | qGroupA.2 | qGroupA.3 | qGroupB.1 | qGroupB.2 | qGroupB.3 | qGroupB.4 | qGroupC.1 | qGroupC.2 | qGroupC.3 | qGroupC.4 | qGroupC.5 | qGroupA_mean | qGroupB_mean | qGroupC_mean | total_mean  | qGroupA_delta | qGroupB_delta | qGroupC_delta | total_delta |
  +---------+-------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+--------------+--------------+--------------+-------------+---------------+---------------+---------------+-------------+
  | A       | pre   | 0.666     | 0.333     | NA        | 1         | 0.666     | 0.666     | 1         | 1         | 1         | 1         | 0.666     | 1         | 0.4995       | 0.833        | 0.9332       | 0.897037394 | NA            | NA            | NA            | NA          |
  | B       | pre   | NA        | 0.333     | 0.333     | 0.666     | 0.666     | 0.666     | 0.666     | 0.666     | 0.666     | 0.666     | 0.666     | 0.666     | 0.333        | 0.666        | 0.666        | 0.575108097 | NA            | NA            | NA            | NA          |
  | A       | post  | 0.666     | 0.333     | 0.333     | 0.666     | 0.666     | 1         | 0.666     | 1         | 1         | 1         | 1         | 1         | 0.444        | 0.7495       | 1            | 0.897037394 | NA            | NA            | NA            | NA          |
  | B       | post  | 0.666     | NA        | 0.333     | 1         | 0         | 1         | 1         | 1         | 0.666     | 0.666     | 1         | 1         | 0.4995       | 0.75         | 0.8664       | 0.575108097 | NA            | NA            | NA            | NA          |
  +---------+-------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+--------------+--------------+--------------+-------------+---------------+---------------+---------------+-------------+
  </code></pre>
  
  <p>Why am I not able to add the values to the dataframe within the lapply function? Is there another, more straight forward way to do what I'm trying to do? </p>