1

I'm aggregating multiple columns in an R data frame using the following method:

data = data.frame(X=c(1, 3, 3), Y=c(2, 3, 3), Z=c(5, 6, 7), ID=c(10, 11, 12))
with(data, aggregate(cbind(Z, ID), list(X=X, Y=Y), c))

However, I want to select columns using a list variable. I've tried some intricate paste statements looking at this question and this question, but I get error messages like "object 'Z' not found".

How do I do this in a short-hand, easy-to-read manner using base R, preferably without libraries, do.call or hard-to-read paste statements full of parenthesis and apostrophes? Ideally:

k = c("Z", "ID")
aggregate(magic(k), list(X=X, Y=Y), data, c)
forthrin
  • 2,709
  • 3
  • 28
  • 50
  • 2
    `aggregate(data[k], data[c("X","Y")], c)` covered in `?aggregate` that there are two forms of syntax. – Frank Sep 08 '17 at 14:24
  • @Frank: `aggregate(data[k], data[c("X","Y")], c)` is short and beautiful! You may post this as a suggested answer. I doubt there will be better suggestions. – forthrin Sep 08 '17 at 15:43

2 Answers2

1

You can do

aggregate(data[k], data[c("X","Y")], c)

A data.frame is a list, so by=data[c("X","Y")] works as needed here.

Frank
  • 66,179
  • 8
  • 96
  • 180
0

Try this:

data = data.frame(X=c(1, 3, 3), Y=c(2, 3, 3), Z=c(5, 6, 7), ID=c(10, 11, 12))

# I would use quote:
by.expr <- quote(cbind(Z, ID))
with(data, aggregate(eval(by.expr), list(X=X, Y=Y), c))

# list-version:
by.l <- list("Z", "ID")
by.expr <- parse(text = paste("cbind(", unlist(by.l), ")"))
with(data, aggregate(eval(by.expr), list(X=X, Y=Y), c))
r.user.05apr
  • 5,356
  • 3
  • 22
  • 39