fubits
fubits

Reputation: 11

R - knitr::kable("html) - col.names from names(list)

I'm working on a blogdown post in RStudio. At one point, a chunks output is a named list with named number vectors, structured like this:

object <- list("Name One" = c("A" = 1, "B" = 1), "Name two" = c("C" = 2, "D" = 2))

What I want to do is to use:

object %>% 
    knitr::kable("html", col.names = X)

to render the output in a nice HTML table. The rendered col.names in this example should be "Name One" and "Name Two".

Of course, something in the manners of col.names = names(object) would be perfect!

This is the error message I receive:

Error in dimnames(x) <- dn : length of 'dimnames' [2] not equal to array extent

I understand that each column header is being a rendered as:

<tr>
  <th style="text-align:left;">   </th>
  <th style="text-align:right;"> x </th>
</tr>

Notice the empty first cell.

Each named number column is being rendered as:

<tr>
  <td style="text-align:left;"> A </td>
  <td style="text-align:right;"> 1 </td>
</tr>
<tr>
  <td style="text-align:left;"> B </td>
  <td style="text-align:right;"> 1 </td>
</tr>

I've tried using a vector c("Name One","name Two"), a vector c("Name One","n","Name Two","n"), and various seq() and rep() combinations without success.

A more realistic example is here Looking forward to any tidy hints.

Edit: I just added object %>% to make my goal more explicit. In order to reproduce this, you would need to run this chunk in R Markdown / Notebook:

object <- list("Name One" = c("A" = 1, "B" = 1), "Name two" = c("C" = 2, "D" = 2))
# cf. names(object)
object %>% 
    knitr::kable("html", col.names = names(object))

Upvotes: 1

Views: 810

Answers (2)

mysteRious
mysteRious

Reputation: 4294

I like Emi's solution above, and also here are two other options that render nicely on web pages including one from my favorite DT package (lots more options at https://rstudio.github.io/DT/ -- there is a lot of whitespace on this one):

library(DT)
data.frame(as.vector(object)) %>% 
    datatable(options=list(dom='t'),colnames=names(object))

enter image description here

Here is another from flextable:

library(flextable)
data.frame(as.vector(object)) %>% 
    regulartable() %>% set_header_labels(names(object))

enter image description here

Upvotes: 0

Emi
Emi

Reputation: 3574

So my guess is that you want a table like (if not do feel free to say so)

<table>
 <thead>
  <tr>
   <th style="text-align:left;"> Name.one </th>
   <th style="text-align:right;"> Name.two </th>
  </tr>
 </thead>
<tbody>
  <tr>
   <td style="text-align:left;"> A </td>
   <td style="text-align:right;"> 1 </td>
  </tr>
  <tr>
   <td style="text-align:left;"> B </td>
   <td style="text-align:right;"> 2 </td>
  </tr>
</tbody>
</table>

For this if you have it in a data.frame (or tibble) format you can generate it via this:

data.frame("Name one"=c("A","B"), "Name two"=c(1, 2)) %>% kable(format="html")

Upvotes: 1

Related Questions