How to pass fun.aggregate as an argument to dcast.data.table?

TL DR: how to pass fun.aggregatein dcast.data.tablewhen the call dcast.data.tableis made within the function (to which I pass fun.aggregate)?

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 reformatted to a long format, keeping the last occurrence 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 transfer my call dcast.data.tableto 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 character fun.aggregate( eval(fun.aggregate)) is evaluated and not found (since the fun.aggregate function does not exist).

How to convey the desired fun.aggregatein f?

(I'm sure this has something to do with quote, substituteetc., but I struggle very much with these functions, and I usually just hook them at random until something works).


Edit:

> sessionInfo()
R version 3.1.0 (2014-04-10)
Platform: x86_64-pc-linux-gnu (64-bit)

...

other attached packages:
[1] data.table_1.9.3

, , 1.9.3 ( dev, ) 1.9.2 ( CRAN).

1.9.2 ( , ), eval()?

+4
1

commit 1303 v 1.9. 3 - . :

dcast.data.table fun.aggregate , fun.aggregate dcast.data.table(). # 713. SO.


, dcast.data.table , - # 715.

, last -1 - fun.aggregate.

last(integer(0))
# [1] integer(0)

fill , , . , .

:

tt <- t[1:5] # t is from your example
dcast.data.table(tt, id ~ k, fun.aggregate=last)
# Error in dcast.data.table(tt, id ~ k, fun.aggregate = last) : 
#   Aggregating function provided to argument 'fun.aggregate' should always return 
#   a length 1 vector, but returns 0-length value for fun.aggregate(integer(0)). 
#   This value will have to be used to fill missing combinations, if any, and 
#   therefore can not be of length 0. Either override by setting the 'fill' argument 
#   explicitly or modify your function to handle this case appropriately.

dcast.data.table(tt, id ~ k, fun.aggregate=last, fill=NA)
#    id a b  c
# 1:  1 1 2  3
# 2:  2 4 5 NA
+4

Source: https://habr.com/ru/post/1546938/


All Articles