Reputation: 21
I would like to use dplyr's rowwise() and the pipe to apply a function (that returns a list) to each row in the dataframe.
Test dataset with two rows:
test_tbl <- tibble(a=c(2, 4), b=c(0, 8), c=c(5, -3))
Defining a simple function (it's about a function returning a list, obviously not about adding 8):
simple_function <- function(input) {
list(input + 8)
}
This is what I would like to achieve:
apply(test_tbl ,1, function (x) simple_function(x))
which returns a list of 2 lists (my desired output).
I would like to save those lists as a column in the tibble. We could do:
test_tbl %>% mutate(output = apply(. ,1, function (x) simple_function(x)))
I'd rather use dplyr than mixing up dplyr, base, and the pipe (also for readability of code), but I do not understand why this doesn't work:
test_tbl %>% rowwise() %>% simple_function
test_tbl %>% rowwise() %>% mutate(output = simple_function(.))
Both of these functions apply the function to the entire dataframe rather than to the seperate rows. It makes no sense to me that:
test_tbl %>% rowwise() %>% simple_function
is identical (in terms of output) to test_tbl %>% simple_function
This does give the desired output, but I find it rather verbose and not ideal that I have to bind the columns myself:
test_tbl %>% rowwise() %>% do(output= simple_function(.)) %>% bind_cols(test_tbl, .)
Any help on why rowwise()
is failing is much appreciated.
Upvotes: 2
Views: 1869
Reputation: 887223
If we need to do this on each row, then split
and apply the function within map
library(tidyverse)
test_tbl %>%
split(., seq_len(nrow(.))) %>%
map(simple_function)
#$`1`
#$`1`[[1]]
# a b c
#1 10 8 13
#$`2`
#$`2`[[1]]
# a b c
#1 12 16 5
Upvotes: 2