Popescu Gabriel
Popescu Gabriel

Reputation: 147

Format multiple flextable columns by user defined function

Is there a way to display the numeric values inside a flextable in millions?

I do not want to divide the numbers in the dataset to 1000000 before creating the flextable.

For example, I want to display the number 1983445678 as 1,983 or 1,983.4 or 1,983.4€

If not, is it possible to implement a new function, maybe similar to set_formatter or colformat_num that allows you to format multiple columns using a user defined function?

Since some columns in my dataset are generated dynamically at runtime (e.g. after using the spread function), I cannot use the function set_formatter to format the new column because I don't know the name of the column yet, when I write the code. Of course, I can detect this name at runtime, so it will be useful to have a function that formats these new columns using a user defined function and accepting in input, the names of the columns to be formatted as strings.

It should be something like:

my_data %>%
regulartable %>%
col_format_by_udf(j = c("Europe", "Asia", "Australia"), million_format)

...or something like:

my_data %>%
regulartable %>%
col_format_num_by_udf(million_format)

All numeric columns are formatted in millions

Thank you!

Upvotes: 1

Views: 946

Answers (2)

David Gohel
David Gohel

Reputation: 10675

You can have a try with this code:


library(magrittr)

dummy_fun <- function(x){
  sprintf("%0.02f", x*1000+pi)
}
funs <- setNames(rep(list(fun), 4), names(iris)[-5])
flextable(head(iris)) %>% 
  set_formatter(values = funs)

enter image description here

Upvotes: 0

Popescu Gabriel
Popescu Gabriel

Reputation: 147

For the moment, I defined a function that solved my problem. It will be usefull if something similar, maybe more elaborated could be inserted into the flextable package directly.

colformat_num_udf <- function(table, j = NULL, udf_function_name = NULL) {

  if (is.null(udf_function_name) | is.null(table))
    return(table)

  if (is.null(j))
    input_columns <- names(table$body$dataset)
  else if(is.numeric(j))
    input_columns <- names(table$body$dataset)[j]
  else
    input_columns <- j

  numeric_columns <- table$body$dataset %>% select_if(is.numeric) %>% names() %>% intersect(input_columns)

  if (length(numeric_columns) == 0)
    return(table)

  rExpression = paste0("table <- set_formatter(table,`", numeric_columns, "` = ", udf_function_name, ")")
  eval(parse(text = rExpression))

  table
}

Upvotes: 1

Related Questions