Make a table row span multiple columns using kable and kableExtra - html

I am trying to create an HTML table using R and the kable and kableExtra packages. I am having problems creating a row that spans several columns. I want to create a table where the last row contains the same values for all the columns without actually repeating this value. I've created a small example of what I am trying to do below.
library(kableExtra)
library(knitr)
summary_stats <- matrix(c(51,43,22,22),ncol=2,byrow=TRUE)
colnames(summary_stats) <- c("Mean","SD")
rownames(summary_stats) <- c("Age","Observations")
summary_stats
kable_table <- kable(summary_stats) %>%
kable_styling()
Instead of repeating the number 22 on the last row for the two columns, I'd like to center it between the two columns.
I am able to achieve what I want with the following HTML code using the colspan argument:
<table class="table" style="margin-left: auto; margin-right: auto;">
<thead>
<tr>
<th style="text-align:left;"> </th>
<th style="text-align:right;"> Mean </th>
<th style="text-align:right;"> SD </th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left;"> Age </td>
<td style="text-align:right;"> 51 </td>
<td style="text-align:right;"> 43 </td>
</tr>
<tr>
<td style="text-align:left;"> Observations </td>
<td style="text-align:center;" colspan = "2"> 22 </td>
</tr>
</tbody>
</table>
Note that the HTML code is just the output of the kable_table object I created in R where I've manually edited the HTML code to include the colspan argument. I would like to do this programmatically within R instead of having to manually change the code.
I've tried to use the row_spec function from the kableExtra package to add the necessary code but I am limited by the fact that the add_css option (as expected) only accepts arguments related to styling. In other words, I cannot pass the colspan argument to the option.
My question is if there is a reasonable way of adding the necessary HTML to the table after I've created it or if there is any option within the kable/kabeExtra framework that allows me to do this that I've missed?

Related

Xpath works in Chrome Dev Tools, but not RSelenium

I have been working on a project to pull an html table that has a specific text ("Current Prison History:") from multiple URLs that change according to one's ID. With that being said, I have tried to use the CSS selector, but the problem with that is because some pages have more tables than others the CSS selector will change by page. Therefore, I thought I would be able to use xpath in order to get the table that I am looking for based on the table's text contents. The HTML is below
<table class="dcCSStableLight" border="1" cellspacing="0" cellpadding="1"
bordercolor="#ececd7">
<tbody>
<tr>
<td class="dark" align="left" colspan="8" bgcolor="#B0C4DE">
<b>Current Prison Sentence History:</b>
</td>
</tr>
<tr bgcolor="#B0C4DE">
<th><b>Offense Date</b>
</th>
<th><b>Offense</b>
</th>
<th><b>Sentence Date</b>
</th>
<th><b>County</b>
</th>
<th><b>Case No.</b>
</th>
<th><b>Prison Sentence Length</b>
</th>
</tr>
<tr valign="top" bgcolor="#FFFFFF">
<td>06/14/2015</td>
<td>BURG/DWELL/OCCUP.CONVEY</td>
<td>08/04/2016</td><td>ST. JOHNS</td>
<td>1501553</td>
<td nowrap="">5Y 0M 0D </td>
</tr>
</tbody>
</table>
I came up with the following xpath to pull the table
//*[#id='dcCSScontentContainer'/div/table/tbody/tr/td/b[contains(text(),"Current")]/ancestor::table
When I check the xpath with Chrome Developer tools it returns the table that I want, however in my R Selenium code, it returns an empty list.
for(i in 1:2){
remDR$navigate(URLs[i])
remDR$screenshot(display=TRUE)
remDR$setImplicitWaitTimeout(10000)
CPSHList[[i]] <- remDR$getPageSource()[[1]] %>%
read_html()%>%
html_nodes(xpath = "//*[#id='dcCSScontentContainer']/div/table/tbody/tr/td/b[contains(text(),'Current')]/ancestor::table")%>%
html_table()%>%
data.frame(stringsAsFactors = FALSE)
}
You should try to find the table that contains a b that has this text.
//table[.//b[contains(text(), 'Current')]]

Incorporating a table inside a table in HTML

I am trying to create an HTML table where there are four columns and any number of rows. Inside this table, the first two columns are just normal cells. The latter two columns can have multiple rows WITHIN a row in the top-level table. My issue is how I can properly align the column separators, even if the length of the content in each cell is variable.
My attempt tries to make use of:
<td colspan=2>
Example of what I am trying to do: https://jsfiddle.net/hurnzhmq/
The things I am missing in the JSFiddle are:
There is no divider between the two rows separating Content3A/Content4A from Content3B/Content4B - I tried using the "bottom-border:none" for the last child, but that did not seem to work.
The column separators between Content3A/Content3B and Content4A/Content4B are not lined up with the header's column separator, and do not touch the ends of the table (there are gaps).
Any advice on how I might go about fixing this would be greatly appreciated!
I think you should use rowspan instead colspan
you can use code below
<html>
<table border=1 >
<tr>
<td>Header1</td>
<td>Header2</td>
<td>Header3</td>
<td>Header4</td>
</tr>
<!-- Content -->
<tr>
<td rowspan="2">Content1</td>
<td rowspan="2" >Content2</td>
<td > Content3A</td>
<td > Content2</td>
</tr>
<tr>
<td > Content3B</td>
<td > Content2</td>
</tr>
</table>
</html>

Angular create table from json resulting in sorted headings

I have an angular app in which i am creating a table based on the json as follows:
<thead>
<tr>
<th ng-repeat="(header, value) in resultData[0]">
{{header}}
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in resultData">
<td ng-repeat="cell in row">
{{cell}}
</td>
</tr>
</tbody>
Here the table creates the headings as well as the content from a json. But the result of this code is a table with sorted headings. Is there a way to keep the order the same as in the json file?
Your headers are in an object. JavaScript objects do not guarantee property order. See this question. To preserve order, you have to use an array in your JSON file.

Colspan with incorrect rows don't render correctly

http://jsfiddle.net/9p7Mx/1/
I'm sure this has been asked before but I can't find the correct search terms:
If you have an HTML table such as:
<table>
<tr>
<td colspan="2"> </td>
<td colspan="2"> </td>
</tr>
<tr>
<td colspan="2"> </td>
<td colspan="2"> </td>
</tr>
<tr>
<td colspan="2"> </td>
<td colspan="2"> </td>
</tr>
<tr>
<td colspan="3"> </td>
<td> </td>
</tr>
</table>
The colspan=3 on the last row will not actually line up correctly because you don't actually have 4 td elements. If you look at my example link, I have two tables, one with two tds with colspan=2 and the last with four actual tds. In the first, the td elements are just mimicking 4 tds with their own colspan=2 and thus I assume the table has no way of knowing exactly how large a single colspan is since there is none. Without knowing the exact with on a single colspan, it appears the table doesn't know what to do.
If I can't change the number of td elements in the table, is it possible to get the same effect? I'd rather not assign a width using CSS, and assigning a width WILL work (tested) but I'd like to see if there is another way.
The markup violates the HTML table model, as http://validator.w3.org tells if you use it in HTML5 mode (“Table column 2 established by element td has no cells beginning in it.”). So you should expect inconsistent and unexpected rendering.
If your table logically has just three columns, make it so. Instead of trying to make some columns wider by using colspan, use CSS to set the widths. The colspan=2 attribute means just that the cell spans two columns. And you cannot validly span a column that does not exist.
Using classes and setting the width for the X% you want.
You must consider some divs instead of a table.

How to extract only the 1st table tag from a html page having various nested table tag

I have the following html page. I want to extract data only within the 1st table tag in C#. the html page code is:
<table cellpadding=2 cellspacing=0 border=0 width=100%>
<tbody>
<tr>
<td align=right><b>11/09/2013 at 09:48</b></td>
</tr>
</tbody>
</table>
<center>
<table border="1" bordercolor="silver" cellpadding="2" cellspacing="0" width="100%">
<thead>
<tr>
<th width=100>ETA</th>
<th width=100>Ship Name</th>
<th width=80>From port</th>
<th width=80>To berth</th>
<th width=130>Agent</th>
</tr>
</thead>
<tbody>
<tr><td>11/09/2013 at 09:00 </td>
<td>SONANGOL KALANDULA </td>
<td>Cabinda </td>
<td>Valero 6 </td>
<td>Graypen </td>
</tr>
</tbody>
</table>
To be more specific I want to extract only the row having date 11/09/2013 at 09:48 the below mentioned code is under the first of tag I am using regex
"<table[^>]*>([^<]*(?:(?!</table)<[^<]*)*)[</table>]*"
but with this I am getting whole of the page source that is I am getting the data between all the table tags but I want only text between first table tag.
Can anyone tell me regular expression with which I can only extract this particular portion from the whole html page?
When trying out your version here, it seems to work to me on the input you specified, though [</table>]* should really be just </table> ([</table>]* means any number of characters in the set: <,/,t,a,b,l,e,>)
This seems like it would bear simplification, though. This should also work:
<table[^>]*>.*?</table>
All bets are off if you have nested tables, of course.