Freitag, 25. Februar 2011

Split - Apply - Combine

Another effort to make groupwise operations with a split - apply - combine solution (maybe we'll need it someday):

d.frm <- data.frame(
    name=c("Max","Max","Max","Max","Max","Moritz","Moritz","Moritz")
  , typ=c("rot","blau","grün","blau","grün","rot","rot","blau")
  , anz=c(5,4,5,8,3,2,9,1) )


# Split to list
groups <- split(d.frm, list(d.frm$name, d.frm$typ))

# Create result vector
results <- vector("list", length(groups))
# Apply
for(i in seq_along(groups)) {
  groups[[i]] <- transform(groups[[i]],
    rank = rank(-anz, ties.method = "first"))
  results[[i]] <- groups[[i]]
}


# Combine
result <- do.call("rbind", results)
result

     name  typ anz rank
2     Max blau   4    2
4     Max blau   8    1
8  Moritz blau   1    1
3     Max grün   5    1
5     Max grün   3    2
6     Max  rot   5    1
61 Moritz  rot   2    2
7  Moritz  rot   9    1


We might want to try here the elegant function ave as well:

d.frm$rank_g <- ave( -d.frm$anz, d.frm$name, d.frm$typ,
  FUN=function(x) rank(x, ties.method="first") )


... and not to forget the specially R-flavour:

split(x, g) <- lapply(split(x, g), FUN)