Search code examples
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("[email protected]", "[email protected]"),
                 to = c("[email protected]", "[email protected]"),
                 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 <- "[email protected]"
to <- "[email protected]"
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("[email protected]", "[email protected]"),
                     to = c("[email protected]", "[email protected]"),
                     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] "[email protected] [email protected] This is test"
    
    [[2]]
    [1] "[email protected] [email protected] This is test"