4

I have a table which I want to display that has a mix of percents, integers, and floating point values each in different rows of the table.

I would like to create formatted output in a R markup or Rnw file that nicely displays my table.

I can do it on a per column basis if I use xtable and the digits command.

I have investigated using the add.to.row functionality of print within a LaTeX output, however, I can not find a LaTeX tag that will apply a format to my numbers, they would all require braces to be around the individual numbers in order for the formatting to take effect, and I can't achieve that.

<<results=tex>>=
  library(xtable)

  ### some random data
  X<-data.frame();
  for (i in 1:2) {
    r<-sample(1:1000,4);
    X<-rbind(X,r);
  }
  X<-rbind(X,(X[1,]/(X[1,]+X[2,])))
  colnames(X)<-c("Cat A","Cat B","Cat C","Cat D")
  rownames(X)<-c("Passed","Failed","Percent Passed")

  ###Atempts to format the rows  
  formTable<-xtable(X)
  print(formTable)

  ###This works to format column
  Y=t(X)
  Y[,"Percent Passed"]=Y[,"Percent Passed"]*100;
  formatedTab<-xtable(Y)
  digits(formatedTab)<-c(0,0,0,2)
  print(formatedTab)
 @

If I could transpose the output of the second table I'd be happy...but that doesn't appear to work.

One particular reason I want this, is that I have very long row descriptions and short column descriptions so it's easier to have nice compact aligned columns.

Techniquab
  • 843
  • 7
  • 22

2 Answers2

3

How about formatting the data frame before calling xtable

library(xtable)
set.seed(10)
X <- as.data.frame(matrix(sample(1:1000, 8), nrow = 2), stringsAsFactors = FALSE)
X[3, ] <- (X[1,]/(X[1,]+X[2,])) * 100
X
#         V1        V2        V3        V4
#1 508.00000 427.00000  85.00000 273.00000
#2 307.00000 692.00000 225.00000 271.00000
#3  62.33129  38.15907  27.41935  50.18382
X <- as.data.frame(lapply(X, sprintf, fmt = c("%.0f", "%.0f", "%.6f")))
colnames(X)<-c("Cat A","Cat B","Cat C","Cat D")
rownames(X)<-c("Passed","Failed","Percent Passed")
formTable<-xtable(X)
formTable
#% latex table generated in R 3.2.0 by xtable 1.7-4 package
#% Tue May  5 11:37:51 2015
#\begin{table}[ht]
#\centering
#\begin{tabular}{rllll}
#  \hline
# & Cat A & Cat B & Cat C & Cat D \\ 
#  \hline
#Passed & 508 & 427 & 85 & 273 \\ 
#  Failed & 307 & 692 & 225 & 271 \\ 
#  Percent Passed & 62.331288 & 38.159071 & 27.419355 & 50.183824 \\ 
#   \hline
#\end{tabular}
#\end{table}
konvas
  • 14,126
  • 2
  • 40
  • 46
  • Hazza...why didn't I think of that before? Well for one thing I need to get more experience with lapply! One thing I would point out for other people using this answer....it's very important that the data going into lapply be a frame for this to work....I have a habit of building my tables starting with NULL and using cbind or r bind and this doesn't work well with your lapply method. – Techniquab May 06 '15 at 04:07
  • If you are just building a small table that's fine, but it's not good practice in general and for larger objects it will lead to long running times and maybe memory issues. So I always avoid using `rbind` in a loop. (see eg section 2 of http://www.burns-stat.com/pages/Tutor/R_inferno.pdf). I realise you may already be aware of this, but I wanted to point it out for other users looking at this answer. – konvas May 06 '15 at 08:57
0

You could format the values dynamically based on whether they ar divisible by one. That way you do not have to do specify the rows specifically:

library(xtable)
library(tidyverse)

### some random data
X<-data.frame();
for (i in 1:2) {
  r<-sample(1:1000,4);
  X<-rbind(X,r);
}
X<-rbind(X,(X[1,]/(X[1,]+X[2,])))
colnames(X)<-c("Cat A","Cat B","Cat C","Cat D")
rownames(X)<-c("Passed","Failed","Percent Passed")


format_int_dbl <- function(vector) {
  result=c()
  for (i in vector){
    if (is.na(i)) {
      formatted_i <- NA
    } else if (((i%% 1) == 0) ) { 
      formatted_i <- sprintf("%i", i)
    } else {
      formatted_i <- sprintf("%.2f", i)
    }
    result <- c(result,formatted_i)
  }
  
  return(result)
}


X <- X %>% mutate_all(.,format_int_dbl)

formTable<-xtable(X)
print(formTable)

% latex table generated in R 4.2.2 by xtable 1.8-4 package
% Fri Apr 14 13:38:43 2023
\begin{table}[ht]
\centering
\begin{tabular}{rllll}
  \hline
 & Cat A & Cat B & Cat C & Cat D \\ 
  \hline
Passed & 330 & 930 & 536 & 525 \\ 
  Failed & 351 & 392 & 622 & 775 \\ 
  Percent Passed & 0.48 & 0.70 & 0.46 & 0.40 \\ 
   \hline
\end{tabular}
\end{table}
Samuel Saari
  • 1,023
  • 8
  • 13