rpurrrsendmailr

Send emails based on data in tibble


I'm trying to iterate over tibble to send emails from each row and can't get it to work. Here is example:

packages

library(tidyverse)
library(sendmailR)
library(pander)

First create table I want to include to email

tbl <- tibble(A = c(1,2,3),
              B = c(4,5,6),
              C = c(7,8,9))

table <- pander_return(tbl)

Create tibble, each column corresponds to certain information I want to include to email

emails <- tibble(from = c("jane.doe@gm.com", "john.doe@gm.com"),
                 to = c("jane.doe@gm.com", "john.doe@gm.com"),
                 subject = "This is test",
                 greetings = "Happy Christmas",
                 data = list(table, table))

Now I would like to map each column and add it to correct place to sendmail function from sendmailR package. Here is example how I can send 1 email. Only interesting bit is how greetings and table are joined together to create msg field.

from <- "jane.doe@gm.com"
to <- "jane.doe@gm.com"
subject <- "This is test"
msg <- c(greetings, table)

sendmailR::sendmail(from = from, to = to, subject = subject, msg = msg)

So how can I map that emails tibble to sendmail function, so email would be sent by each row.


Solution

  • This is a perfect use case for the pmap function from purrr

    You could do the following

    pmap( list(emails$from, emails$to, emails$subject, emails$data) 
          , ~sendmailR::sendmail(from = ..1, 
                                to = ..2, 
                                subject = ..3, 
                                msg = ..4))
    

    This creates a list of arguments, then using the ~ we define the function. The ..x represent the order that the arguments appear in the input list.

    Full reprex

    library(tidyverse)
    library(sendmailR)
    library(pander)
    
    tbl <- tibble(A = c(1,2,3),
                  B = c(4,5,6),
                  C = c(7,8,9))
    
    table <- pander_return(tbl)
    
    emails <- tibble(from = c("jane.doe@gm.com", "john.doe@gm.com"),
                     to = c("jane.doe@gm.com", "john.doe@gm.com"),
                     subject = "This is test",
                     greetings = "Happy Christmas",
                     data = list(greetings, table))
    
    pmap( list(emails$from, emails$to, emails$subject, emails$data) 
          , ~sendmailR::sendmail(from = ..1, 
                                to = ..2, 
                                subject = ..3, 
                                msg = ..4))
    
    

    And just to show it works with a lower stakes function:

    pmap( list(emails$from, emails$to, emails$subject, emails$data) 
          , ~paste(..1, 
                                ..2, 
                                ..3))
    

    Outputs:

    [[1]]
    [1] "jane.doe@gm.com jane.doe@gm.com This is test"
    
    [[2]]
    [1] "john.doe@gm.com john.doe@gm.com This is test"