HSC
HSC

Reputation: 129

R two way table percentage with total response count

ID <- c(1:10)
hotel <- c("A","B","C","A","B","C","A","B","C","A")
satisfied <- c("disagree","agree","strongly agree","disagree","agree","strongly disagree","agree","disagree","strongly disagree","strongly agree")
df <- data.frame( ID,hotel,satisfied) 

mytable <- table(df$hotel,df$satisfied) # hotel will be rows, satisfied will be columns
addmargins(mytable)

portion <- prop.table(mytable, 1) # row percentages

I would like to make a table as below. Please help me how to add total response, overall % and the column sorting order.

enter image description here

Upvotes: 0

Views: 1039

Answers (2)

AnilGoyal
AnilGoyal

Reputation: 26238

This is where library janitor helps

library(janitor)
df %>% tabyl(hotel, satisfied) %>%
  adorn_totals(c("row", "col")) %>%
  adorn_percentages("row") %>%
  adorn_pct_formatting(2)

 hotel  agree disagree strongly agree strongly disagree   Total
     A 25.00%   50.00%         25.00%             0.00% 100.00%
     B 66.67%   33.33%          0.00%             0.00% 100.00%
     C  0.00%    0.00%         33.33%            66.67% 100.00%
 Total 30.00%   30.00%         20.00%            20.00% 100.00%

Even you may show both proportion and percentages, nicely formatted like a text table

df %>% tabyl(hotel, satisfied) %>%
  adorn_totals(c("row", "col")) %>%
  adorn_percentages("row") %>%
  adorn_pct_formatting(2) %>%
  adorn_ns("front")

 hotel      agree   disagree strongly agree strongly disagree        Total
     A 1 (25.00%) 2 (50.00%)     1 (25.00%)        0  (0.00%)  4 (100.00%)
     B 2 (66.67%) 1 (33.33%)     0  (0.00%)        0  (0.00%)  3 (100.00%)
     C 0  (0.00%) 0  (0.00%)     1 (33.33%)        2 (66.67%)  3 (100.00%)
 Total 3 (30.00%) 3 (30.00%)     2 (20.00%)        2 (20.00%) 10 (100.00%)

Upvotes: 2

IRTFM
IRTFM

Reputation: 263441

Save the added margins and reorder with [, cols], then focusing only on first 4 columns: divide by the grand sum, multiply by 100 and paste0 "%"

marg.tbl <- addmargins(mytable)[ , c(3,2,2,4,5)]
> marg.tbl
     
      strongly agree disagree disagree strongly disagree Sum
  A                1        2        2                 0   4
  B                0        1        1                 0   3
  C                1        0        0                 2   3
  Sum              2        3        3                 2  10

 marg.tbl[ , 1:4] <- round( 100*marg.tbl[ , 1:4]/marg.tbl[4,5])
 marg.tbl[ , 1:4] <- paste0(marg.tbl[ , 1:4], "%")

> marg.tbl
     
      strongly agree disagree disagree strongly disagree Sum
  A   10%            20%      20%      0%                4  
  B   0%             10%      10%      0%                3  
  C   10%            0%       0%       20%               3  
  Sum 20%            30%      30%      20%               10 

Upvotes: 1

Related Questions