Dan Chaltiel | 075db09 | 2020-08-03 22:18:33 +0200 | [diff] [blame] | 1 | #' Remove columns |
| 2 | #' |
| 3 | #' @param kable_input Output of [knitr::kable()] with format specified |
| 4 | #' @param columns A numeric value or vector indicating in which column(s) rows need to be removed |
| 5 | #' |
| 6 | #' @export |
| 7 | #' |
| 8 | #' @examples |
| 9 | #' mtcars %>% |
| 10 | #' kable() %>% |
| 11 | #' remove_column(2:3) |
Dan Chaltiel | 9e83d8f | 2020-08-03 22:46:35 +0200 | [diff] [blame] | 12 | remove_column <- function (kable_input, columns) { |
Dan Chaltiel | 075db09 | 2020-08-03 22:18:33 +0200 | [diff] [blame] | 13 | kable_format <- attr(kable_input, "format") |
| 14 | if (!kable_format %in% c("html", "latex")) { |
| 15 | warning("Please specify format in kable. kableExtra can customize either ", |
| 16 | "HTML or LaTeX outputs. See https://haozhu233.github.io/kableExtra/ ", |
| 17 | "for details.") |
| 18 | return(kable_input) |
| 19 | } |
| 20 | if (kable_format == "html") { |
| 21 | return(remove_column_html(kable_input, columns)) |
| 22 | } else if (kable_format == "latex") { |
| 23 | stop("Removing columns was not implemented for latex kables yet") |
| 24 | } |
| 25 | } |
| 26 | |
| 27 | remove_column_html <- function (kable_input, columns) { |
| 28 | kable_attrs <- attributes(kable_input) |
| 29 | kable_xml <- kable_as_xml(kable_input) |
| 30 | kable_tbody <- xml_tpart(kable_xml, "tbody") |
| 31 | kable_thead <- xml_tpart(kable_xml, "thead") |
| 32 | |
| 33 | cell_topleft <- xml2::xml_child(kable_thead, 1) %>% |
| 34 | xml2::xml_child(1) %>% |
| 35 | xml2::xml_text() %>% |
| 36 | stringr::str_trim() |
| 37 | has_rownames <- cell_topleft=="" |
Dan Chaltiel | 075db09 | 2020-08-03 22:18:33 +0200 | [diff] [blame] | 38 | |
Dan Chaltiel | c0d3029 | 2020-08-04 00:17:24 +0200 | [diff] [blame] | 39 | head_row <- xml2::xml_child(kable_thead, 1) |
| 40 | ncols <- xml2::xml_length(head_row) |
| 41 | body_nrows <- xml2::xml_length(kable_tbody) |
| 42 | |
| 43 | rowspan = matrix(1, nrow = body_nrows, ncol=ncols) |
| 44 | for(i in 1:body_nrows){ |
| 45 | target_row <- xml2::xml_child(kable_tbody, i) |
| 46 | target_ncols <- xml2::xml_length(target_row) |
| 47 | for(j in 1:target_ncols){ |
Dan Chaltiel | 075db09 | 2020-08-03 22:18:33 +0200 | [diff] [blame] | 48 | target_cell <- xml2::xml_child(target_row, j) |
Dan Chaltiel | c0d3029 | 2020-08-04 00:17:24 +0200 | [diff] [blame] | 49 | span = as.numeric(xml2::xml_attr(target_cell, "rowspan")) %>% replace_na(0) |
| 50 | if(span>0){ |
| 51 | rowspan[i,j]=1 |
| 52 | rowspan[i+seq(from=1, to=span-1),j]=0 |
| 53 | } |
| 54 | } |
| 55 | } |
| 56 | |
| 57 | for(i in 1:body_nrows){ |
| 58 | target_row <- xml2::xml_child(kable_tbody, i) |
Dan Chaltiel | f8f0616 | 2020-08-04 00:33:55 +0200 | [diff] [blame^] | 59 | for(j in rev(columns)){ |
Dan Chaltiel | c0d3029 | 2020-08-04 00:17:24 +0200 | [diff] [blame] | 60 | target_cell <- xml2::xml_child(target_row, j) |
| 61 | if(rowspan[i,j]==1) |
Dan Chaltiel | 075db09 | 2020-08-03 22:18:33 +0200 | [diff] [blame] | 62 | xml2::xml_remove(target_cell) |
| 63 | } |
| 64 | } |
Dan Chaltiel | c0d3029 | 2020-08-04 00:17:24 +0200 | [diff] [blame] | 65 | |
Dan Chaltiel | 075db09 | 2020-08-03 22:18:33 +0200 | [diff] [blame] | 66 | for(j in columns){ |
Dan Chaltiel | c0d3029 | 2020-08-04 00:17:24 +0200 | [diff] [blame] | 67 | target_cell_head <- xml2::xml_child(head_row, j) |
Dan Chaltiel | 075db09 | 2020-08-03 22:18:33 +0200 | [diff] [blame] | 68 | xml2::xml_remove(target_cell_head) |
| 69 | } |
| 70 | out <- as_kable_xml(kable_xml) |
| 71 | attributes(out) <- kable_attrs |
| 72 | if (!"kableExtra" %in% class(out)) |
| 73 | class(out) <- c("kableExtra", class(out)) |
| 74 | |
| 75 | return(out) |
| 76 | } |