Question

I am using prettyNum in combination with xtable to produce nice LaTeX tables. It works as expected when I have more than one row in the data.frame. But when I only have one row it fails because prettyNum converts the data.frame to a character vector.

Is there a simple way similar to "drop = FALSE" to retain a data.frame from prettyNum?

df <- data.frame(a = 1, b ='a')
prettyDf <- prettyNum(df) 
class(prettyDf)
[1] "character"
Was it helpful?

Solution

There are two basic options you can use: convert the output to a one-row matrix before using xtable, or you can use apply to convert to prettyNum.

Here is a minimal example:

First, some sample data. A one row data.frame and a three row data.frame:

df <- structure(
  list(V1 = 76491283764.9743, V2 = 29.12345678901, V3 = -7.1234, V4 = -100.1, 
       V5 = 1123), .Names = c("V1", "V2", "V3", "V4", "V5"), 
  row.names = c(NA, -1L), class = "data.frame")
df
#            V1       V2      V3     V4   V5
# 1 76491283765 29.12346 -7.1234 -100.1 1123

df2 <- rbind(df, df*2, df*3)
df2
#             V1       V2       V3     V4   V5
# 1  76491283765 29.12346  -7.1234 -100.1 1123
# 2 152982567530 58.24691 -14.2468 -200.2 2246
# 3 229473851295 87.37037 -21.3702 -300.3 3369

Using xtable on the 3-row one works fine, but unlike what you stated in your question, it does not retain a data.frame. It converts the output to a character matrix.:

> class(prettyNum(df2, big.mark=","))
[1] "matrix"

> xtable(prettyNum(df2, big.mark=","), align = "rrrrrr")
% latex table generated in R 2.15.3 by xtable 1.7-1 package
% Fri Mar 22 15:46:08 2013
\begin{table}[ht]
\centering
\begin{tabular}{rrrrrr}
  \hline
 & V1 & V2 & V3 & V4 & V5 \\ 
  \hline
1 &  76,491,283,765 &        29.12346 &         -7.1234 &          -100.1 &           1,123 \\ 
  2 & 152,982,567,530 &        58.24691 &        -14.2468 &          -200.2 &           2,246 \\ 
  3 & 229,473,851,295 &        87.37037 &        -21.3702 &          -300.3 &           3,369 \\ 
   \hline
\end{tabular}
\end{table}

Trying the same on the 1-row data.frame gives us an error, because in the process of "prettifying" your numbers, the data.frame becomes a named character vector, as you already figured out:

> xtable(prettyNum(df, big.mark = ","), align = "rrrrrr")
Error in UseMethod("xtable") : 
  no applicable method for 'xtable' applied to an object of class "character"

Use methods(xtable) to see the types of objects for which xtable methods have been defined. To view a specific method--for example, the xtable.data.frame method--use xtable:::xtable.data.frame. From there, you can learn how to write your own method if you think it's necessary.

However, in this case, it's not necessary. Just try one of the following options, noting the subtle difference between the them:

xtable(matrix(prettyNum(df, big.mark = ","), nrow = 1), align = "rrrrrr")
xtable(t(apply(df, 1, prettyNum, big.mark = ",")), align = "rrrrrr")

Here is some sample output:

enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top