quick question: alternatives to a short but a bit involved code

Viewed 53

I'm trying to produce a string with the specifications (colnames and max string length of each column):

library(tidyverse)
df <- tibble::tribble(
  ~nif, ~dni_check,
  "33333457V", "33333457",
  "44817563Q", "44817563",
  "33256164G", "33256164",
  "36050083K", "36050083"
)
df %>%
  summarise(across(everything(), ~ str_c(" C(", max(str_length(.)), ")"))) %>%
  map2_chr(colnames(.), ., str_c) %>%
  str_c(collapse = "; ")
#> [1] "nif C(9); dni_check C(8)"

Just out of curiosity, would you propose an alternative, maybe in a shorter or neater way?

2 Answers

We could use cur_column that provides the column name and then with sprintf creates the format in the summarised columns, reduce it to a single string with str_c

library(dplyr)
library(stringr)
library(purrr)
df %>% 
   summarise(across(everything(), 
      ~ sprintf('%s C(%d)', cur_column(), max(str_length(.))))) %>%    
   reduce(str_c, sep ='; ')

-output

#[1] "nif C(9); dni_check C(8)"

Or with glue create the format

library(glue)
df %>% 
   summarise(across(everything(), 
       ~ glue('{cur_column()} C({max(str_length(.))})')))

-output

# A tibble: 1 x 2
#  nif      dni_check     
#  <glue>   <glue>        
#1 nif C(9) dni_check C(8)

Or can use imap to paste the names and max number of characters and then reduce to a single string

library(purrr)
imap(df, ~ sprintf('%s C(%d)', .y, max(str_length(.x)))) %>%     
       reduce(str_c, sep ='; ')

-output

#[1] "nif C(9); dni_check C(8)"

A base R option

paste0(
  do.call(
    sprintf,
    c(
      fmt = "%s C(%d)",
      rev(stack(sapply(df, function(v) max(nchar(v)))))
    )
  ),
  collapse = "; "
)

gives

"nif C(9); dni_check C(8)"
Related