close
Skip to content

dcast.data.table eval(fun.aggragate) -- cannot pass as an argument #713

@mathematicalcoffee

Description

@mathematicalcoffee

Referred from SO question

Affects 1.9.3 (and not 1.9.2)

TL;DR

If you have a function that calls dcast.data.table, you can't seem to pass fun.aggregate into that call from the function argument.
Because of an eval(fun.aggregate) within dcast.data.table.

Example

I have a table like this:

library(data.table)
t <- data.table(id=rep(1:2, c(3,4)), k=c(rep(letters[1:3], 2), 'c'), v=1:7)
t
   id k v
1:  1 a 1
2:  1 b 2
3:  1 c 3
4:  2 a 4
5:  2 b 5
6:  2 c 6
7:  2 c 7  # note the duplicate (2, c)

I reshape to long format, retaining the last occurence of duplicates

dcast.data.table(t, id ~ k, value.var='v', fun.aggregate=last) # last is in data.table
   id a b c
1:  1 1 2 3
2:  2 4 5 7

However if I wrap my dcast.data.table call into a function:

f <- function (tbl, fun.aggregate) {
    dcast.data.table(tbl, id ~ k, value.var='v', fun.aggregate=fun.aggregate)
}
f(t, last)
Error in `[.data.table`(data, , eval(fun.aggregate), by = c(ff_)) : 
  could not find function "fun.aggregate"

It looks like the symbol fun.aggregate is being evaluated (eval(fun.aggregate)) and not found (since the function "fun.aggregate" does not exist).

Is there a way to "protect" a function argument from the eval() call when I pass it in (i.e. perhaps this behaviour is intended), or perhaps this is a bug. My personal opinion is that it is a bug, because this works for dcast and not dcast.data.table, and the two should be consistent.

Metadata

Metadata

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions