-3

I have a table that looks like this:

+-----------------------------------+-------+--------+------+
|                                   | Male  | Female |  n   |
+-----------------------------------+-------+--------+------+
| way more than my fair share       | 2,4   | 21,6   |  135 |
| a little more than my fair share  | 5,4   | 38,1   |  244 |
| about my fair share               | 54,0  | 35,3   |  491 |
| a littles less than my fair share | 25,1  | 3,0    |  153 |
| way less than my fair share       | 8,7   | 0,7    |   51 |
| Can't say                         | 4,4   | 1,2    |   31 |
| n                                 | 541,0 | 564,0  | 1105 |
+-----------------------------------+-------+--------+------+

Everything is fine but what I would like to do is to show no digits in the last row at all since they show the margins (real cases). Is there any chance in R I can manipulate specific cells and their digits?

Thanks!

b_schmidl
  • 81
  • 7

1 Answers1

1

You could use ifelse to output the numbers in different formats in different rows, as in the example below. However, it will take some additional finagling to get the values in the last row to line up by place value with the previous rows:

library(knitr)
library(tidyverse)

# Fake data
set.seed(10)
dat = data.frame(category=c(LETTERS[1:6],"n"), replicate(3, rnorm(7, 100,20)))

dat %>% 
  mutate_if(is.numeric, funs(sprintf(ifelse(category=="n", "%1.0f", "%1.1f"), .))) %>% 
  kable(align="lrrr")
|category |    X1|    X2|    X3|
|:--------|-----:|-----:|-----:|
|A        | 100.4|  92.7| 114.8|
|B        |  96.3|  67.5| 101.8|
|C        |  72.6|  94.9|  80.9|
|D        |  88.0| 122.0|  96.1|
|E        | 105.9| 115.1| 118.5|
|F        | 107.8|  95.2| 109.7|
|n        |    76|   120|    88|

The huxtable package makes it easy to decimal-align the values (see the Vignette for more on table formatting):

library(huxtable)

tab = dat %>% 
  mutate_if(is.numeric, funs(sprintf(ifelse(category=="n", "%1.0f", "%1.1f"), .))) %>% 
  hux %>% add_colnames()

align(tab)[-1] = "."

tab

Here's what the PDF output looks like when knitted to PDF from an rmarkdown document:

enter image description here

eipi10
  • 91,525
  • 24
  • 209
  • 285
  • 1
    A little code-golf? `sprintf(ifelse(category=="n", "%1.0f", "%1.1f"), .)` – r2evans Jul 12 '18 at 18:13
  • Thanks. That works. I don't really understand the code though. Have to check it out. Unfortunately I also need the third column to have no digits. Any additional help would be much appreciated. – b_schmidl Jul 12 '18 at 18:35
  • 1
    `sprintf` is a formatting function (see `?sprintf` for details). `"%1.0f"` means format with no decimal places, `"%1.1f"` means format with one decimal place. You can apply the `"%1.0f"` format to the entire third column and then format the the other two numeric columns separately. More generally, the key idea is that you're converting the numbers to text strings for output to a table, and using conditional statements or other methods of row and column selection to format each cell in the way you desire. – eipi10 Jul 12 '18 at 18:39
  • Thanks. But why doesn't df$n <- sprintf("%1.0f", df$n) work? – b_schmidl Jul 12 '18 at 18:52
  • Because it is a character now I guess!? – b_schmidl Jul 12 '18 at 18:55
  • Perhaps change from `mutate_if(is.numeric` to `mutate_at(vars(Male,Female)`, that will preserve the `numeric` nature of `$n`. – r2evans Jul 12 '18 at 18:58