title: faster way to create variable that aggregates a column by id
body: <p>Is there a faster way to do this? I guess this is unnecessary slow and that a task like this can be accomplished with base functions.</p>
  
  <pre><code>df &lt;- ddply(df, "id", function(x) cbind(x, perc.total = sum(x$cand.perc)))
  </code></pre>
  
  <p>I'm quite new to R. I have looked at <code>by()</code>, <code>aggregate()</code> and <code>tapply()</code>, but didn't get them to work at all or in the way I wanted. Rather than returning a shorter vector, I want to attach the sum to the original dataframe. What is the best way to do this?</p>
  
  <p>Edit: Here is a speed comparison of the answers applied to my data. </p>
  
  <pre><code>&gt; # My original solution
  &gt; system.time( ddply(df, "id", function(x) cbind(x, perc.total = sum(x$cand.perc))) )
     user  system elapsed 
   14.405   0.000  14.479 
  
  &gt; # Paul Hiemstra
  &gt; system.time( ddply(df, "id", transform, perc.total = sum(cand.perc)) )
     user  system elapsed 
   15.973   0.000  15.992 
  
  &gt; # Richie Cotton
  &gt; system.time( with(df, tapply(df$cand.perc, df$id, sum))[df$id] )
     user  system elapsed 
    0.048   0.000   0.048 
  
  &gt; # John
  &gt; system.time( with(df, ave(cand.perc, id, FUN = sum)) )
         user  system elapsed 
        0.032   0.000   0.030 
  
  &gt; # Christoph_J
  &gt; system.time( df[ , list(perc.total = sum(cand.perc)), by="id"][df])
     user  system elapsed 
    0.028   0.000   0.028 
  </code></pre>