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: 
One way using `data.table`

```
df <- structure(list(V1 = structure(c(1L, 1L, 2L, 2L, 2L, 3L), 
          .Label = c("A  ", "B  ", "C  "), class = "factor"), 
          V2 = c(45, 66, 99, 34, 71, 22)), 
          .Names = c("V1", "V2"), 
          class = "data.frame", row.names = c(NA, -6L))

require(data.table)
dt <- data.table(df, key="V1")

# get maximum index
idx <- max(dt[, .N, by=V1]$N)

# get final result
dt[, list(V2 = c(V2, rep(0, idx-length(V2)))), by=V1]

#     V1 V2
# 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

```
Here is a `dplyr` option:

```
library(dplyr)

# Get maximum number of rows for all groups
N = max(count(df,id)$n)

df %>% 
  group_by(id) %>% 
  summarise(amount = c(amount, rep(0, N-length(amount))), .groups = "drop")

```

**Output**

```
  id    amount
  <chr>  <dbl>
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

```