Search code examples
rmatrixdataframextable

Combining matrix in data frame through aggregate


I'm trying to compute quantiles by factor and print out the resulting aggregate to latex format using xtable. Unfortunately, I'm getting some wonky behavior. And a clean solution would be appreciated.

To create an example:

tm <- data.frame(f=c("a","b","c"),v=runif(30))
tm$f <- factor(tm$f)
agv <- aggregate(v~f,tm, quantile)

The output agv isn't accepted by xtable:

xtable(agv)

gives

Error in cols[, i + pos] <- do.call("formatC", curFormatArgs) : number of items to replace is not a multiple of replacement length

even though print(agv) is

  f        v.0%       v.25%       v.50%       v.75%      v.100%
1 1 0.002970944 0.253247687 0.571891610 0.766606825 0.986142807
2 2 0.002129951 0.328739086 0.558132094 0.799115979 0.991067470
3 3 0.011059184 0.285322522 0.496035672 0.770908599 0.994420787

because apparently dim(agv) is actually [1] 3 2

So I tried:

cbind(featureName=agv$f, agv$v)

which results in the character factors converting to numeric values for some reason.

After some trial and error, this is the solution I settled on:

cbind(f=as.character(agv$f), data.frame(agv$v,check.names=F))

which, gives me the result I want in xtable:

\begin{table}[ht]
\centering
\begin{tabular}{rlrrrrr}
  \hline
 & f & 0\% & 25\% & 50\% & 75\% & 100\% \\
  \hline
1 & a & 0.00 & 0.25 & 0.48 & 0.75 & 0.99 \\
  2 & b & 0.00 & 0.28 & 0.46 & 0.74 & 1.00 \\
  3 & c & 0.02 & 0.21 & 0.44 & 0.63 & 1.00 \\
   \hline
\end{tabular}
\end{table}

Anyway, I'm just curious whether there's a cleaner solution with fewer lines involved.


Solution

  • A slightly more direct approach (though not much different conceptually than what you've already done) might be to use do.call(data.frame, ...). The following works for me.

    xtable(do.call(data.frame, c(agv, check.names = FALSE)))
    

    For me, that returns:

    > xtable(do.call(data.frame, c(agv, check.names = FALSE)))
    % latex table generated in R 3.0.0 by xtable 1.7-1 package
    % Thu Apr 25 11:10:26 2013
    \begin{table}[ht]
    \centering
    \begin{tabular}{rlrrrrr}
      \hline
     & f & v.0\% & v.25\% & v.50\% & v.75\% & v.100\% \\ 
      \hline
    1 & a & 0.06 & 0.27 & 0.38 & 0.64 & 0.94 \\ 
      2 & b & 0.20 & 0.38 & 0.52 & 0.70 & 0.87 \\ 
      3 & c & 0.01 & 0.22 & 0.60 & 0.87 & 0.99 \\ 
       \hline
    \end{tabular}
    \end{table}
    

    xtable also works with data.tables, so you can also do something like the following:

    library(data.table)
    
    DT <- data.table(tm, key = "f")
    xtable(DT[, as.list(quantile(v)), by = key(DT)])
    

    Here, DT[, as.list(quantile(v)), by = key(DT)] will give you the same results as your "agv" object.