Solved: RE: xtable does not print out units of a variable

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Solved: RE: xtable does not print out units of a variable

Shawn Way-4
Jeff, John,

Thanks for pointing out the information.  I found that the following works:


New function for deparsing the data:

deparse_unit_latex <- function(x,frac=TRUE,xtable.frac=FALSE)
{
    stopifnot(inherits(x, "units"))
    u = units(x)
    tn = table(u$numerator)
    nm1 = names(tn)
    vals1 = as.character(tn)
    vals1 <- paste("^",vals1,sep="")
    vals1[vals1 == "^1"] = ""
    td = table(u$denominator)
    nm2 = names(td)
    vals2 = as.character(td)
    vals2 <- paste("^",vals2,sep="")
    vals2[vals2 == "^1"] = ""
    if(frac == TRUE) {
        if (xtable.frac==FALSE) {
            if(is.null(nm1)) {
                res <- cat(paste(c("$\\frac{}{",paste0(nm2, vals2),"}$"), collapse = " "))
            } else if(is.null(nm2)) {
                res <- paste(c("$",paste0(nm1, vals1),"$"), collapse = " ")
            } else {
                res <- cat(paste(c("$\\frac{",paste0(nm1, vals1),"}{",paste0(nm2, vals2),"}$"), collapse = " "))
            }
        }
        if (xtable.frac == TRUE) {
            if(is.null(nm1)) {
                res <- paste(paste0("$\\frac{}{",paste0(nm2, vals2),"}$"), collapse = " ")
            } else if(is.null(nm2)) {
                res <- paste(c("$",paste0(nm1, vals1),"$"), collapse = " ")
            } else {
                res <- paste(paste0("$\\frac{",paste0(nm1, vals1),"}{",paste0(nm2, vals2),"}$"), collapse = " ")
            }
        }
    }
    if(frac == FALSE) {
        if(xtable.frac == TRUE){
            if(is.null(nm1)) {
                res <- paste(c("$/",paste0(nm2, vals2),"$"), collapse = " ")
            } else if(is.null(nm2)) {
                res <- paste(c("$",paste0(nm1, vals1),"$"), collapse = " ")
            } else {
                res <- paste(c("$",paste0(nm1, vals1),"/",paste0(nm2, vals2),"$"), collapse = " ")
            }
        }
        if(xtable.frac == FALSE){
            if(is.null(nm1)) {
                res <- paste(c("$/",paste0(nm2, vals2),"$"), collapse = " ")
            } else if(is.null(nm2)) {
                res <- paste(c("$",paste0(nm1, vals1),"$"), collapse = " ")
            } else {
                res <- paste(c("$",paste0(nm1, vals1),"/",paste0(nm2, vals2),"$"), collapse = " ")
            }
        }
    }
    res
}

Modification to xtable:

xtable <- function(x, ...) {
    for (i in which(sapply(x, function(y) !all(is.na(match(c("POSIXt","Date"),class(y))))))) x[[i]] <- as.character(x[[i]])
    for (i in which(sapply(x, function(y) !all(is.na(match(c("units"),class(y))))))) x[[i]] <- as.character(paste(as.character(x[[i]]),deparse_unit_latex(x[[i]],...)))
    xtable::xtable(x, ...)
}

Finally:

data <- data.frame(x=c(as_units(12,"kg/(m*sec^2)")),y=c(as_units(13,"kg/sec")),z=c(as_units(13,"ft^2")),zz=c(as_units(13,"sec-1")))

print(xtable(data,frac=FALSE,xtable.frac=TRUE),sanitize.text.function = function(x){x})

% latex table generated in R 3.5.1 by xtable 1.8-2 package
% Thu Jul 19 16:30:17 2018
\begin{table}[ht]
\centering
\begin{tabular}{rllll}
  \hline
 & x & y & z & zz \\
  \hline
1 & 12 $ kg / m s^2 $ & 13 $ kg / s $ & 13 $ ft^2 $ & 13 $/ s $ \\
   \hline
\end{tabular}
\end{table}
>


Or

> print(xtable(data,frac=TRUE,xtable.frac=TRUE),sanitize.text.function = function(x){x})
% latex table generated in R 3.5.1 by xtable 1.8-2 package
% Thu Jul 19 16:33:41 2018
\begin{table}[ht]
\centering
\begin{tabular}{rllll}
  \hline
 & x & y & z & zz \\
  \hline
1 & 12 $\frac{kg}{m}$ $\frac{kg}{s^2}$ & 13 $\frac{kg}{s}$ & 13 $ ft^2 $ & 13 $\frac{}{s}$ \\
   \hline
\end{tabular}
\end{table}
>


Thanks for all your help.

Shawn Way, PE


-----Original Message-----
From: Jeff Newmiller <[hidden email]>
Sent: Wednesday, July 18, 2018 9:26 PM
To: Shawn Way <[hidden email]>
Cc: [hidden email]
Subject: Re: [R] xtable does not print out units of a variable

On Wed, 18 Jul 2018, Shawn Way wrote:

> I have a dataframe that contains units using the units package.
> Unfortunately, I really need the units for reporting.  I'm assuming
> that's because the data is in a class units and xtable doesn't know
> what to do with this.

If you want a bug or feature in a CONTRIBUTED PACKAGE, then you need to communicate with the maintainer:

maintainer( "xtable" )

Do keep in mind that they almost always volunteer their time, so be patient, and consider figuring out what code changes they need to make so it will work.

More below.

> The following is a MWE:
>
>    library(xtable)
>    library(units)
>    data <- data.frame(x=c(as_units(12,"ft")))
>    xtable(data)
>
>    % latex table generated in R 3.5.1 by xtable 1.8-2 package
>    % Wed Jul 18 17:31:44 2018
>    \begin{table}[ht]
>    \centering
>    \begin{tabular}{rr}
>      \hline
>     & x \\
>      \hline
>    1 & 12.00 \\
>      \hline
>    \end{tabular}
>    \end{table}
>
> What I'm looking for is the line
>
>    1 & 12.00 \\
>
> to be
>
>    1 & 12.00 $ft$\\
>
> Can someone point me in the correct direction to make this happen?
> Since units are used extensively in engineering calculations, being
> able to handle this class would be extremely beneficial to engineers
> that are using R with knitr to generate engineering documents.
>
> Shawn Way

I do want to emphasize that R focuses on consistency among elements within columns, not rows, so putting the units into the body of the table is kind of visually redundant in most cases. Consider:

####################
library(xtable)
library(units)
#> udunits system database from /usr/share/xml/udunits data <- data.frame(x=c(as_units(c(12,13),"ft")))
datax <- xtable(data)
names(datax) <- paste0( names(datax)[1]
                       , " ($"
                       , deparse_unit( datax[[1]] )
                       , "$)"
                       )
datax
#> % latex table generated in R 3.4.4 by xtable 1.8-2 package #> % Wed Jul 18 19:13:29 2018 #> \begin{table}[ht] #> \centering #> \begin{tabular}{rr}
#>   \hline
#>  & x (\$ft\$) \\
#>   \hline
#> 1 & 12.00 \\
#>   2 & 13.00 \\
#>    \hline
#> \end{tabular}
#> \end{table}

#' Created on 2018-07-18 by the [reprex package](http://reprex.tidyverse.org) (v0.2.0).
####################

If you have some kind of summary table with different units on each row, then you will probably arrive at that information a single-row, many column data frame. I usually transpose this into a three-column data frame with a description column, a value column, and a units column. I don't use the units package so have never tried to adapt it to that process.

> ______________________________________________
> [hidden email] mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide
> http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>

---------------------------------------------------------------------------
Jeff Newmiller                        The     .....       .....  Go Live...
DCN:<[hidden email]>        Basics: ##.#.       ##.#.  Live Go...
                                       Live:   OO#.. Dead: OO#..  Playing
Research Engineer (Solar/Batteries            O.O#.       #.O#.  with
/Software/Embedded Controllers)               .OO#.       .OO#.  rocks...1k

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.