0

I have create a function that builds a tibble from a few basic inputs

library(tidyverse)
fun <- function(x, y) {
  tibble(
    start = x) %>%
  mutate(k = x * y)
}

What I would like to do is set the class of each variable within this function.

fun <- function(x, y) {
  tibble(
    start = x) %>%
  mutate(k = x * y) %>%
  mutate_at(vars(x, k), "currency")
}

I've tried

fun <- function(x, y) {
  tibble(
    start = x) %>%
  mutate(k = x * y) %>%
  class(k) <- "currency"
}

My goal is to create a tibble that includes classes in them for later export using the openxlsx package. I've found lots of ways to convert from factors to numeric, etc. using the mutate_at function, but cannot find a way to define the class of a tibble (or data frame) variable in the same function it is create. I know I can do this in a script easy enough, but it seems like something I should be able to do within a function.

1 Answers1

1

Where is the "currency" class from? The closest I could find was formattable::currency (even that returns class "formattable" "numeric") . In which case, you can do :

library(dplyr)

fun <- function(x, y) {

  tibble(start = x) %>%
    mutate(k = x * y) %>%
    mutate_at(vars(start, k), formattable::currency)
}

fun(1:10, 2)
# A tibble: 10 x 2
#   start      k         
#   <formttbl> <formttbl>
# 1 $1.00      $2.00     
# 2 $2.00      $4.00     
# 3 $3.00      $6.00     
# 4 $4.00      $8.00     
# 5 $5.00      $10.00    
# 6 $6.00      $12.00    
# 7 $7.00      $14.00    
# 8 $8.00      $16.00    
# 9 $9.00      $18.00    
#10 $10.00     $20.00    

Even if it is from some different package you would be able to do the same with the default methods present in the class. For example, to change it to "character" class you could use :

fun <- function(x, y) {
   tibble(start = x) %>%
     mutate(k = x * y) %>%
     mutate_at(vars(start, k), as.character)
}

EDIT

fun <- function(x, y) {

  data <- tibble(start = x) %>% mutate(k = x * y)
  data[c('k', 'start')] <- lapply(data[c('k', 'start')], 
                             function(x) {class(x) <- "Currency";x})
   return(data)
}

str(fun(1:10, 2))
#Classes ‘tbl_df’, ‘tbl’ and 'data.frame':  10 obs. of  2 variables:
# $ start: 'Currency' int  1 2 3 4 5 6 7 8 9 10
# $ k    : 'Currency' num  2 4 6 8 10 12 14 16 18 20
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
  • The "currency" class is coming from `openxlsx` package – Scott Davidson Mar 23 '20 at 15:41
  • I tried adding: `mutate_at(vars(start, k), openxlsx::currency)` but it is say "Error: 'currency' is not an exported object from 'namespace:openxlsx'" – Scott Davidson Mar 23 '20 at 16:04
  • is there an alternative way to set a class for multiple objects in a data frame? `class(vars(df$start, k)) <- "currency"` – Scott Davidson Mar 23 '20 at 16:10
  • Thank you Ronak. I’ve gotten so used to Tidyverse, forgot to use old school skills. I appreciate the help. – Scott Davidson Mar 24 '20 at 05:31
  • If you want to stay in `tidyverse`, you can change `lapply` to `map` and this would work the same. – Ronak Shah Mar 24 '20 at 05:33
  • I will have to read up on ‘map’. I’ve never been very good with the various apply functions. A lot of brute force scripting is my usual method. Tidyverse has made entry into learning R much easier. I think it is time for me to study up on map. Thanks again Ronak. I really appreciate the help. – Scott Davidson Mar 25 '20 at 06:07