In R data.table, it is possible to reshape on multiple columns by passing a list of column names (value.var=) along with a list of aggregation functions (fun.aggregate=). This works well when those lists are explicitly passed to the function arguments. It appears to result in an error condition if the lists are passed as variables.
For example, lets create a data table dt
as follows:
dt = data.table(x=sample(5,20,TRUE), y=sample(2,20,TRUE),
z=sample(letters[1:2], 20,TRUE), d1 = runif(20), d2=1L)
The reshape operation on two columns, d1 and d1, works with arguments passed as follows:
dcast(dt, x + y ~ z, fun=list(sum, mean), value.var=list("d1", "d2"))
However, the same operations fails when arguments are passed as named variables.
funs = list(sum, mean)
vars = list("d1", "d2")
dcast(dt, x + y ~ z, fun=funs, value.var=vars)
The error message is:
Error in aggregate_funs(fun.call, lvals, sep, ...) :
When 'fun.aggregate' and 'value.var' are both lists, 'value.var' must be either of length =1 or =length(fun.aggregate)
Is this a bug, or am I going about this the wrong way?
Update: Tried in R version 3.5.0 and data.table version 1.11.4 on Windows. In the actual scenario, my table has 171 columns and over 300,000 rows. The pivot operation involves 31 columns. I have unexpectedly encountered an error in trying to pass function arguments as variables instead of long "in situ" lists. I am looking for an explanation why this error condition occurs. Thank you!
aggregate_funs
function indata.table
package. I would think about submitting an issue to thedata.table
Github repo, as this shouldn't be considered wanted behaviour. – Blaza...fun=list(sum, mean), value.var=list("d1", "d2")
and that works, as the OP said already. When you instead pass variables which are lists, as..., fun=funs, value.var=vars)
, the error appears. That is the problem that the OP is talking about. Do you not get an error even when running the last 3 lines of code in the question? – Blazadcast(dt, x + y ~ z, fun=funs, value.var=c("d1","d2"))
work for you? I get an error again that a functionfuns
could not be found. That indicates that there is a bug in parsing the fun argument if it's passed as a variable. Passing everything withlist(...), list(...)
(orc(...)
) like in the example isn't answering the OP's problem, but rather providing a workaround, which the OP explicitly said s/he wants to avoid, as s/he (I would presume) wants to avoid hard coding the fun and value.var arguments. – Blaza