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,651
  • 2
  • 24
  • 48
  • 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
  • 65,012
  • 8
  • 95
  • 173
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
  • 4,939
  • 3
  • 18
  • 37