R Convert a datatable into percentage table columnwise

Viewed 363

I am trying to convert this table into percentage table columnwise.

Class Jan2021 Feb 2021
A 50 100
B 50 150
C 100 100

I am expecting this table.

Class Jan2021 Feb 2021
A 25% 28.57%
B 25% 42.86%
C 50% 28.57%
x <- data.frame(class = c("A", "B", "C"),
                Jan2021 = c(50,50,100),
                Feb2021 = c(100,150,100))

I could do this, but I have lots of columns/rows with different names. Is there an easier way to calculate the percentage for each column?

x_pct = mutate(x, 
            Jan_pct = Jan2021 / sum(Jan2021) *100,
            Feb_pct = Feb2021 / sum(Feb2021) *100)
3 Answers

You can use dplyr::mutate_if() and scales::percent:

x %>% 
  mutate_if(endsWith(names(.),"2021"),function(x) x / sum(x)) %>% 
  mutate_if(endsWith(names(.),"2021"),scales::percent, accuracy = 0.01)

Output:

  class Jan2021 Feb2021
1     A  25.00%  28.57%
2     B  25.00%  42.86%
3     C  50.00%  28.57%

You can use across -

library(dplyr)

x %>%  mutate(across(-class, ~paste(round(prop.table(.) * 100, 2), '%')))

#  class Jan2021 Feb2021
#1     A    25 % 28.57 %
#2     B    25 % 42.86 %
#3     C    50 % 28.57 %

Or lapply in base R -

x[-1] <- lapply(x[-1], function(x) paste(round(prop.table(x) * 100, 2), '%'))
library(janitor)
x %>%
  adorn_percentages("col") %>%
  adorn_pct_formatting(digits = 2)


 class Jan2021 Feb2021
     A  25.00%  28.57%
     B  25.00%  42.86%
     C  50.00%  28.57%
Related