Question: I have this data.frame:

```
df <- data.frame(id=c('A','A','B','B','B','C'), amount=c(45,66,99,34,71,22))

id | amount 
-----------
A  |   45   
A  |   66   
B  |   99
B  |   34 
B  |   71
C  |   22

```

which I need to expand so that each `by` group in the data.frame is of equal length (filling it out with zeroes), like so:

```
id | amount 
-----------
A  |   45   
A  |   66  
A  |   0     <- added 
B  |   99
B  |   34 
B  |   71
C  |   22
C  |   0     <- added 
C  |   0     <- added 

```

What is the most efficient way of doing this?

**NOTE**

Benchmarking the some of the solutions provided with my *actual* 1 million row data.frame I got:

```
             plyr   | data.table  |  unstack
          -----------------------------------
Elapsed:   139.87s  |    0.09s    |   2.00s

```

Answer: 
I'm sure there is a base R solution, but here is one that uses `ddply` in the `plyr` package

```
library(plyr)
##N: How many values should be in each group
N = 3
ddply(df, "id", summarize, 
      amount = c(amount, rep(0, N-length(amount))))

```

gives:

```
  id amount
1  A     45
2  A     66
3  A      0
4  B     99
5  B     34
6  B     71
7  C     22
8  C      0
9  C      0

```
How about this?

```
out <- by(df, INDICES = df$id, FUN = function(x, N) {
  x <- droplevels(x)
  lng <- nrow(x)
  dif <- N - lng
  if (dif == 0) return(x)
  make.list <- lapply(1:dif, FUN = function(y) data.frame(id = levels(x$id), amount = 0))
  rbind(x, do.call("rbind", make.list))
  }, N = max(table(df$id))) # N could also be an integer
do.call("rbind", out)

    id amount
A.1  A     45
A.2  A     66
A.3  A      0
B.3  B     99
B.4  B     34
B.5  B     71
C.6  C     22
C.2  C      0
C.3  C      0

```