Search code examples
rtidyverseapplygt

Using dataframe variable as argument in user-defined function


I would like to pass a variable in a dataframe to a function I've written. The function works, creating a png file with the gt package, when I manually type in a file name as the argument. However, when I attempt to pass a column in a dataframe that contains all the filenames needed to the function, it fails. I would like to create all the png files needed using the values in the column.

I can't share the real data. Fictional and simplified example follows.

Creating data

library(tidyverse)
library(gt)

# function makes png file from dataframe x 
makGt <- function(x) {
  select(x , fName) %>%
    gt(.) %>%
    gtsave(sprintf('fab4%s.png' , x[1,1]))
}

# example data
fName <- c('John' , 'Paul' , 'George' , 'Ringo')
byr <- c(1940 , 1942 , 1943 , 1940)
beatles <- data.frame(fName , byr) %>% arrange(fName)

# make individual files for each beatle
purrr::set_names(beatles %>% 
                   group_by(fName) %>%
                   group_split(), beatles$fName) %>%
  list2env(envir = globalenv())

Save a gt table in png format for George using the dataframe George

makGt(George) # creates png file for George using function

Futile attempts (two of many) to create png files using values from beatles$fName.

# attempts to use beatles fName variable in function makGt
makGt(sprintf('fab4%s' , beatles[1,1])) # results in error
sapply(beatles$fName , FUN = makGt) # error is same as above

Tidyverse-friendly code would be appreciated or using apply family. Many thanks for any help.


Solution

  • Inside the makGt function, you'll need to get() the value of the object (which is in your case, get the dataframes created by purrr from fName).

    library(tidyverse)
    library(gt)
    
    fName <- c('John' , 'Paul' , 'George' , 'Ringo')
    byr <- c(1940 , 1942 , 1943 , 1940)
    beatles <- data.frame(fName , byr) %>% arrange(fName)
    
    purrr::set_names(beatles %>% 
                       group_by(fName) %>%
                       group_split(), beatles$fName) %>%
      list2env(envir = globalenv())
    
    makGt <- function(x) {
      get(beatles$fName[x])[1] %>% 
        gt() %>% 
        gtsave(filename = sprintf('fab4%s.png' , 
                                  beatles[x, 1]),
               path = getwd())
    }
    
    sapply(1:nrow(beatles), makGt)
    

    This will save four .png files in your working directory with the name fab4[fName].png. I've included fab4George.png as an example output.

    fab4George