Search code examples
rtidyverserowtibble

How to apply multiple columns to a function, one at a time


I have a tibble with two columns. For each row, I want to use the values from the two columns in a function. What is the proper way to do this using tidyverse? As I will describe in more detail below, I don't think the function (call to an API) can be vectorized.

To set ideas, suppose that I have these data:

library(tidyverse)
d <- tibble(a=c("a", "b", "d"), b=c("x", "y", "z"))

I then want to apply a function (here, just a very simple thing). Using base R, I can do:

for (i in 1:nrow(d)) {
    d[i, "value"] <- paste0(d[i,"a"], d[i, "b"])
}

What is the best way---tidyverse solution is hoped for, but not necessary---to do this for each row, passing to the function two arguments?

Note that I am aware that in the above example, I could do d <- d %>% mutate(value = paste0(a, b)), however my actual problem involves an R function that performs an API call to a specific API that I think needs to be run one row at a time. Each call to the API returns a list, which I want to store in my tibble.

Also note that I may need to have a small lag between each API call.


Solution

  • Use rowwise, map2_chr, mapply or Vectorize :

    # 1
    library(dplyr)
    f <- paste  # replace with your function
    d %>%
      rowwise %>%
      mutate(value = f(a, b)) %>%
      ungroup
    
    # 2 - replace map2_chr with map2_dbl if output of f is double
    library(dplyr)
    library(purrr)
    d %>% mutate(value = map2_chr(a, b, f))
    
    # 3
    library(dplyr)
    d %>% mutate(value = mapply(f, a, b))
    
    # 4
    library(dplyr)
    d %>% mutate(value = Vectorize(f)(a, b))