R/html_matrix.R

Defines functions hm_tr hm_col hm_row hm_table hm_title hm_index hm_cell hm_pos html_matrix.default html_matrix

Documented in hm_cell hm_col hm_index hm_row hm_table hm_title hm_tr html_matrix html_matrix.default

#' @rdname html_matrix
#' @title HTML Representation 
#' @aliases html_mx
#' @description Creates from a vector, a matrix, an array, or a table, an HTML representation of it. The HTML representation has one column and one row more 
#' than the data. The additional row and column are used in order to have a title (top left), the column names (top), and the row names (left).
#' 
#' You can set the style attributes (`<td style="...">`) via `hm_cell`, `hm_title`, `hm_col`, and `hm_row`. 
#' For example: `hm_cell(hm, 1, 1, text_align="right")` will lead to (`<td style="text-align:right;">`) for the cell (1,1), and any
#' unnamed element will change the cell value. 
#' Note: since `-` is an operator in R, we use `_` instead. Of course, someone could use `"text-align"="right"`, but I am lazy.
#' 
#' @param x vector, matrix, array, table or html_matrix: input.
#' @param byrow logical: creates a row or column matrix if `x` is one-dimensional (default: \code{FALSE})
#' @param numeric list: of HTML style properties for a cell if `class(x[i,j])=="numeric"` (default: \code{list(text_align="right")})
#' @param integer list: of HTML style properties for a cell if `class(x[i,j])=="integer"` (default: \code{list(text_align="right")})
#' @param char list: of HTML style properties for a cell if `class(x[i,j])=="character"` (default: \code{list(text_align="left")})
#' @param logical list: of HTML style properties for a cell if `class(x[i,j])=="logical"` (default: \code{list(text_align="right")})
#' @param border character: vector of background color for a border cell (default: \code{"#999999")})
#' @param ... further parameters
#'
#' @return Returns an `html_matrix`.
#' @export
#'
#' @examples
#' m <- matrix(1:6, ncol=2)
#' m
#' l <- html_matrix(m)
#' l
html_matrix <- function(x, ...) { UseMethod("html_matrix") }

#' @rdname html_matrix
#' @export
html_matrix.default <- function(x, ..., byrow=FALSE, 
                                numeric=list(text_align="right"), 
                                integer=list(text_align="right"), 
                                char=list(text_align="left"),
                                logical=list(text_align="right"),
                                border="#999999") {
  title <- deparse(substitute(x))
  val   <- as.list(x) 
  dim   <- attr(x, "dim")
  rownames <- colnames <- NULL
  if (length(dim)<2) {
    if (byrow) { 
      dim <- c(length(val), 1) 
      colnames <- names(x)
    } else {
      dim <- c(1, length(val))    
      rownames <- names(x)
    }
  } else {
    if (length(dim)>2) dim <- c(dim[1], prod(dim[-1]))
    colnames <- colnames(x)
    rownames <- rownames(x)
  }
  if (is.null(colnames)) colnames <- sprintf("[,%.0f]", seq(dim[2]))
  if (is.null(rownames)) rownames <- sprintf("[%.0f,]", seq(dim[1]))
  cols <- vector("list", length(colnames))
  for (i in seq(colnames)) cols[[i]] <- list(value=colnames[i], fmt="%s", text_align="right", background_color=border, vertical_align="top", font_weight="bold", min_width="60px")
  rows <- vector("list", length(rownames))
  for (i in seq(rownames)) rows[[i]] <- list(value=rownames[i], fmt="%s", text_align="left", background_color=border, vertical_align="top", font_weight="bold")
  ret  <- vector("list", length(val))
  for (i in seq(val)) {
    reti <- list()
    if("integer" %in% class(val[[i]])) {
      reti <- numeric
      if (is.null(reti$fmt)) reti$fmt <- "%.0f"
    }
    if("numeric" %in% class(val[[i]])) {
      reti <- numeric
      if (is.null(reti$fmt)) reti$fmt <- "%.3f"
    }
    if("logical" %in% class(val[[i]])) {
      reti <- logical
      if (is.null(reti$fmt)) reti$fmt <- "%.0f"
    }
    if("character" %in% class(val[[i]])) {
      reti <- char
      if (is.null(reti$fmt)) reti$fmt <- "%s"
    }
    reti$value <- val[[i]]
    ret[[i]]   <- reti
  }
  #
  attr(ret, "title")    <- list(value=title, fmt="%s", text_align="left", background_color=border, vertical_align="top", font_weight="bold")
  attr(ret, "rownames") <- rows
  attr(ret, "colnames") <- cols
  attr(ret, "tr") <- vector("list", 1+length(rows))
  attr(ret, "table") <- list()
  structure(ret, dim=dim, class=c("html_matrix", class(ret)))
}

hm_pos <- function(nrow, ...) {
  #browser()
  args   <- list(...)
  pos <- matrix(NA_integer_, nrow=nrow, ncol=length(args))
  for (j in seq(args)) pos[,j] <- rep(1:length(args[[j]]), length.out=nrow) 
  nargs <- names(args)
  if (is.null(nargs)) nargs <- rep('', length(args))
  nargs[nargs==''] <- 'value'
  list(argpos=pos, nargs=nargs)
}

#' @rdname hm_cell
#' @title `html_mmatrix` Modification
#' @aliases hm_index 
#' @aliases hm_row 
#' @aliases hm_col 
#' @aliases hm_title
#' @aliases hm_tr
#' @aliases hm_table 
#' @aliases modify_cell
#' @aliases mod_cell
#' @aliases modify_col
#' @aliases mod_col 
#' @aliases modify_index 
#' @aliases mod_ind
#' @aliases modify_row 
#' @aliases mod_row 
#' @aliases modify_table 
#' @aliases mod_t
#' @aliases modify_title
#' @aliases mod_title 
#' @aliases modify_tr 
#' @aliases mod_tr
#' @description
#' * `hm_cell` or `hm_index` modify a data cell format (`fmt="%s"`), value (unnamed parameter) or style (`text_align="left"`)
#' * `hm_col` or `hm_row` modify a row or column format (`fmt="%s"`), value (unnamed parameter) or style (`text_align="left"`)
#' * `hm_title` modifies the title attribute of an `html_matrix` based on specific arguments
#' * `hm_table` modifies the properties of the entire HTML table within an `html_matrix`
#' * `hm_tr` modifies the properties of one or more table rows (tr elements) in an `html_matrix`. Row indices for modification (`ind`) can be specified along with additional parameters to customize the row format, values, or style
#' @param x an `html_matrix` object
#' @param row integer: row(s) to access
#' @param col integer: column(s) to access
#' @param ind integer vector or matrix: has access to various (row and columns) elements (first column: row, second column: column)
#' @param byrow logical: order indices by row or column (default: \code{FALSE})
#' @param ... further elements 
#'
#' @md
#' @return A modified `html_matrix` object.
#' @export
#'
#' @examples
#' l <- html_matrix(matrix(1:6, ncol=2))
#' # replace l[1,1] by NA
#' hm_cell(l, 1, 1, NA)
#' # replace l[1,1] by NA and set the text_align to center
#' hm_cell(l, 1, 1, NA, text_align="center")
#' # replace l[1,3] and l[2,1] by NA
#' rcind <- cbind(c(1,3), c(2, 1))
#' hm_index(l, rcind, NA)
#' # set a new title
#' hm_title(l, "new title")
#' # set a new row or column title
#' hm_row(l, 2, "row 2")
#' hm_col(l, 1, "col 1")
#' # set fmt by column or row
#' print(hm_cell(l, fmt=c("%.0f", "%.1f", "%.2f"), byrow=FALSE), which="fmt")
#' print(hm_cell(l, fmt=c("%.0f", "%.1f"), byrow=TRUE), which="fmt")
hm_cell  <- function(x, row=NULL, col=NULL, ..., byrow=FALSE) { 
  #browser()
  stopifnot("html_matrix" %in% class(x))
  if (is.null(row)) row <- seq(nrow(x))
  if (is.null(col)) col <- seq(ncol(x))
  ind <- expand.grid(row, col)
  ind <- if (byrow) ind[order(ind[,1], ind[,2]),] else ind[order(ind[,2], ind[,1]),]
  hm_index (x, ind, ...)
}

#' @rdname hm_cell
#' @export
hm_index <- function(x, ind, ...)    {
  stopifnot("html_matrix" %in% class(x))
  stopifnot(length(dim(x))==2)
  pos  <- hm_pos(nrow=nrow(ind), ...)
  args <- list(...)
  for (i in 1:nrow(ind)) {
    for (j in seq(args)) {
      x[[ind[i,1], ind[i,2]]][[pos$nargs[j]]] <- args[[j]][pos$argpos[i,j]]
    }
  }
  x
}

#' @rdname hm_cell
#' @export
hm_title <- function(x, ...) {
  stopifnot("html_matrix" %in% class(x))
  pos   <- hm_pos(nrow=1, ...)
  args  <- list(...)
  param <- attr(x, "title")
  for (j in seq(args)) {
    param[[pos$nargs[j]]] <- args[[j]][pos$argpos[1,j]]
  }
  attr(x, "title") <- param
  x
}    

#' @rdname hm_cell
#' @export
hm_table <- function(x, ...) {
  stopifnot("html_matrix" %in% class(x))
  pos   <- hm_pos(nrow=1, ...)
  args  <- list(...)
  param <- attr(x, "table")
  for (j in seq(args)) {
    param[[pos$nargs[j]]] <- args[[j]][pos$argpos[1,j]]
  }
  attr(x, "table") <- param
  x
}    
      
#' @rdname hm_cell
#' @export
hm_row <- function(x, ind, ...)  {
  stopifnot("html_matrix" %in% class(x))
  pos   <- hm_pos(nrow=length(ind), ...)
  args  <- list(...)
  param <- attr(x, "rownames")
  for (i in 1:length(ind)) {
    for (j in seq(args)) {
      param[[i]][[pos$nargs[j]]] <- args[[j]][pos$argpos[i,j]]
    }
  }
  attr(x, "rownames") <- param
  x
}

#' @rdname hm_cell
#' @export
hm_col <- function(x, ind, ...) {
  stopifnot("html_matrix" %in% class(x))
  pos   <- hm_pos(nrow=length(ind), ...)
  args  <- list(...)
  param <- attr(x, "colnames")
  for (i in 1:length(ind)) {
    for (j in seq(args)) {
      param[[i]][[pos$nargs[j]]] <- args[[j]][pos$argpos[i,j]]
    }
  }
  attr(x, "colnames") <- param
  x
}

#' @rdname hm_cell
#' @export
hm_tr <- function(x, ind, ...) {
  stopifnot("html_matrix" %in% class(x))
  pos   <- hm_pos(nrow=length(ind), ...)
  args  <- list(...)
  param <- attr(x, "tr")
  for (i in 1:length(ind)) {
    for (j in seq(args)) {
      param[[i]][[pos$nargs[j]]] <- args[[j]][pos$argpos[i,j]]
    }
  }
  attr(x, "tr") <- param
  x
}

#' @rdname html_matrix
#' @export
# html_mx <- function(...){
#  html_matrix(...)} 
html_mx <- html_matrix

#' @rdname hm_cell
#' @export
# modify_cell <- function(...){
#  hm_cell(...)} 
modify_cell <- hm_cell

#' @rdname hm_cell
#' @export
# mod_cell <- function(...){
#  hm_cell(...)} 
mod_cell <- hm_cell

#' @rdname hm_cell
#' @export
# modify_col <- function(...){
#  hm_col(...)} 
modify_col <- hm_col

#' @rdname hm_cell
#' @export
# mod_col <- function(...){
#  hm_col(...)} 
mod_col <- hm_col

#' @rdname hm_cell
#' @export
# modify_index <- function(...){
#  hm_index(...)} 
modify_index <- hm_index

#' @rdname hm_cell
#' @export
# mod_ind <- function(...){
#  hm_index(...)} 
mod_ind <- hm_index

#' @rdname hm_cell
#' @export
# modify_row <- function(...){
#  hm_row(...)} 
modify_row <- hm_row

#' @rdname hm_cell
#' @export
# mod_row <- function(...){
#  hm_row(...)} 
mod_row <- hm_row

#' @rdname hm_cell
#' @export
# modify_table <- function(...){
#  hm_table(...)} 
modify_table <- hm_table

#' @rdname hm_cell
#' @export
# mod_t <- function(...){
#  hm_table(...)} 
mod_t <- hm_table

#' @rdname hm_cell
#' @export
# modify_title <- function(...){
#  hm_title(...)} 
modify_title <- hm_title

#' @rdname hm_cell
#' @export
# mod_title <- function(...){
#  hm_title(...)} 
mod_title <- hm_title

#' @rdname hm_cell
#' @export
# modify_tr <- function(...){
#  hm_tr(...)} 
modify_tr <- hm_tr

#' @rdname hm_cell
#' @export
# mod_tr <- function(...){
#  hm_tr(...)} 
mod_tr <- hm_tr

Try the exams.forge package in your browser

Any scripts or data that you put into this service are public.

exams.forge documentation built on Sept. 11, 2024, 5:32 p.m.