blob: 828edaecb4b8152fb86712a9fd608ae63b727e6e [file] [log] [blame]
#' Remove columns
#'
#' @param kable_input Output of [knitr::kable()] with format specified
#' @param columns A numeric value or vector indicating in which column(s) rows need to be removed
#'
#' @export
#'
#' @examples
#' mtcars %>%
#' kable() %>%
#' remove_column(2:3)
remove_column <- function (kable_input, columns) {
if(is.null(columns)) return(kable_input)
kable_format <- attr(kable_input, "format")
if (!kable_format %in% c("html", "latex")) {
warning("Please specify format in kable. kableExtra can customize either ",
"HTML or LaTeX outputs. See https://haozhu233.github.io/kableExtra/ ",
"for details.")
return(kable_input)
}
if (kable_format == "html") {
return(remove_column_html(kable_input, columns))
} else if (kable_format == "latex") {
stop("Removing columns was not implemented for latex kables yet")
}
}
remove_column_html <- function (kable_input, columns) {
kable_attrs <- attributes(kable_input)
kable_xml <- kable_as_xml(kable_input)
kable_tbody <- xml_tpart(kable_xml, "tbody")
kable_thead <- xml_tpart(kable_xml, "thead")
cell_topleft <- xml2::xml_child(kable_thead, 1) %>%
xml2::xml_child(1) %>%
xml2::xml_text() %>%
stringr::str_trim()
has_rownames <- cell_topleft==""
head_row <- xml2::xml_child(kable_thead, 1)
ncols <- xml2::xml_length(head_row)
body_nrows <- xml2::xml_length(kable_tbody)
rowspan = matrix(1, nrow = body_nrows, ncol=ncols)
for(i in 1:body_nrows){
target_row <- xml2::xml_child(kable_tbody, i)
target_ncols <- xml2::xml_length(target_row)
for(j in 1:target_ncols){
target_cell <- xml2::xml_child(target_row, j)
span = as.numeric(xml2::xml_attr(target_cell, "rowspan")) %>% replace_na(0)
if(span>0){
rowspan[i,j]=1
rowspan[i+seq(from=1, to=span-1),j]=0
}
}
}
for(i in 1:body_nrows){
target_row <- xml2::xml_child(kable_tbody, i)
for(j in rev(columns)){
target_cell <- xml2::xml_child(target_row, j)
if(rowspan[i,j]==1)
xml2::xml_remove(target_cell)
}
}
for(j in columns){
target_cell_head <- xml2::xml_child(head_row, j)
xml2::xml_remove(target_cell_head)
}
out <- as_kable_xml(kable_xml)
attributes(out) <- kable_attrs
if (!"kableExtra" %in% class(out))
class(out) <- c("kableExtra", class(out))
return(out)
}