Return a list in dplyr mutate()
The idiomatic way to do this using data.table
would be to use the :=
(assignment by reference) operator. Here's an illustration:
it[, c(paste0("V", 4:5)) := myfun(V2, V3)]
If you really want a list, why not:
as.list(it[, myfun(V2, V3)])
Alternatively, maybe this is what you want, but why don't you just use the data.table
functionality:
it[, c(.SD, myfun(V2, V3))]# V1 V2 V3 V4 V5# 1: a 1 2 3 -1# 2: a 2 3 5 -1# 3: b 3 4 7 -1# 4: b 4 2 6 2# 5: c 5 2 7 3
Note that if myfun
were to name it's output, then the names would show up in the final result columns:
# V1 V2 V3 new.1 new.2# 1: a 1 2 3 -1# 2: a 2 3 5 -1# 3: b 3 4 7 -1# 4: b 4 2 6 2# 5: c 5 2 7 3
Given the title to this question, I thought I'd post a tidyverse
solution that uses dplyr::mutate
. Note that myfun
needs to output a data.frame
to work.
library(tidyverse)it = data.frame( v1 = c("a","a","b","b","c"), v2 = c(1,2,3,4,5), v3 = c(2,3,4,2,2))myfun = function(arg1,arg2) { temp1 = arg1 + arg2 temp2 = arg1 - arg2 data.frame(temp1, temp2)}it %>% nest(data = c(v2, v3)) %>% mutate(out = map(data, ~myfun(.$v2, .$v3))) %>% unnest(cols = c(data, out))#> # A tibble: 5 x 5#> v1 v2 v3 temp1 temp2#> <fct> <dbl> <dbl> <dbl> <dbl>#> 1 a 1 2 3 -1#> 2 a 2 3 5 -1#> 3 b 3 4 7 -1#> 4 b 4 2 6 2#> 5 c 5 2 7 3
Created on 2020-02-04 by the reprex package (v0.3.0)
The mutate() function is designed to add new columns to the existing data frame. A data frame is a list of vectors of the same length. Thus, you cant add a list as a new column, because a list is not a vector.
You can rewrite your function as two functions, each of which return a vector. Then apply each of these separately using mutate() and it should work.