Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dplyr : use mutate with columns that contain lists

Tags:

r

dplyr

I have the following dataframe (sorry for not providing an example with dput, it doesn't seem to work with lists when I paste it here):

data

Now I am trying to create a new column y that takes the difference between mnt_opeand ref_amountfor each element of ref_amount. The result would be, in each row, a list with the same number of elements as the corresponding value of ref_amount.

I have tried:

data <- data %>%
   mutate( y = mnt_ope - ref_amount)

But I get as error:

Evaluation error: non-numeric argument to binary operator.

With dput :

structure(list(mnt_ope = c(500, 500, 771.07, 770.26, 770.26, 
770.26, 770.72, 770.72, 770.72, 770.72, 770.72, 779.95, 779.95, 
779.95, 779.95, 2502.34, 810.89, 810.89, 810.89, 810.89, 810.89
), ref_amount = list(c(500, 500), c(500, 500), c(771.07, 770.26, 
770.26), c(771.07, 770.26, 770.26), c(771.07, 770.26, 770.26), 
    c(771.07, 770.26, 770.26), c(771.07, 770.26, 770.26), c(771.07, 
    770.26, 770.26), c(771.07, 770.26, 770.26), c(771.07, 770.26, 
    770.26), c(771.07, 770.26, 770.26), c(771.07, 770.26, 770.26
    ), c(771.07, 770.26, 770.26), c(771.07, 770.26, 770.26), 
    c(771.07, 770.26, 770.26), 2502.34, c(810.89, 810.89, 810.89
    ), c(810.89, 810.89, 810.89), c(810.89, 810.89, 810.89), 
    c(810.89, 810.89, 810.89), c(810.89, 810.89, 810.89))), row.names = c(NA, 
-21L), class = c("tbl_df", "tbl", "data.frame"))
like image 623
Vincent Avatar asked Jul 03 '18 14:07

Vincent


1 Answers

You can't subtract directly from a list column in that way using dplyr. The best way I have found to accomplish the task you are referencing is to use purrr::map. Here is how it works:

data <- data %>% mutate(y = map2(mnt_ope, ref_amount, function(x, y){ x - y }))

Or, more tersely:

data <- data %>% mutate(y = map2(mnt_ope, ref_amount, ~.x - .y))

map2 here applies a two-input function to two vectors (in your case, two columns of a data frame) and returns the result as a vector (which we are using mutate to append back to your data frame).

Hope that helps!

like image 176
Robert Kahne Avatar answered Oct 04 '22 22:10

Robert Kahne