通过Rmarkdown中数据行数函数设置绘图高度等于相邻表格高度

Mar*_*rri 7 r ggplot2 r-markdown

我正在使用 mtcars 数据在 Rmarkdown 中创建并排图和表格。

---
title: "document"
author: "Maral Dorri"
date: 'May 2022'
output:
  html_document
---
Run Code Online (Sandbox Code Playgroud)

我创建一个列并在右侧添加表格:

<div class = "row">
<div class = "col-md-3">
```{r}
raw_dat <- mtcars[1:15, ] %>% rownames_to_column(var = "id") %>% select(id, mpg) %>% 
  mutate(links = paste(.$id, "And <a href = 'https://www.cars.com//'>here</a>"))
tibble(
  name = raw_dat$id,
  link = paste(raw_dat$mpg, "And <a href = 'https://www.cars.com//'>here</a>")) %>%
  mutate(link = map(link, gt::html)) %>%
  gt

```
</div>
Run Code Online (Sandbox Code Playgroud)

然后我创建另一列并打印左侧的图

<div class = "col-md-9">
```{r, fig.height=5.5}
   ggplot(raw_dat, aes(factor(id, rev(id)), mpg)) +
   geom_point() +
   coord_flip() +
   theme(plot.margin = margin(0.6, unit = "cm"))
```
</div>
</div>
Run Code Online (Sandbox Code Playgroud)

结果是:

在此输入图像描述

我知道我可以手动设置图形的高度并捕获与右侧表格相同的大小,但我想使其自动,因为对于我的实际数据,它会定期更改。因此,用于绘图高度的函数应该以表中数据的行数为单位。

所需的输出会将右侧表中的每一行数据与左侧图的 y 轴标签对齐,如图所示(手动完成,未完全对齐)

在此输入图像描述

Kat*_*Kat 8

再次更新...

好吧,这将一直有效,直到绘图扩展至绘图边距超出表格标题行的高度(大约 15 行)

这是样式和JS。

<style>
.main-container {
  max-width: unset;
}
</style>


```{r listen,results="asis",engine="js"}
// tbl font size is 1em (assuming-- rendered 16px; the padding t/b 8px)
// do what you're told 
setTimeout(function(){  // add to buttons
  ch = document.querySelector('.col-md-3').clientHeight; // how tall is the table
  sh = document.querySelector('.col-md-9');              // pull the 2nd column for manipulation
  si = document.querySelector('img');                    // assuming there's only one plot
  sih = si.clientHeight;                                 // plot height
  siw = si.clientWidth;                                  // plot width
  fs = $('.gt_table').css('line-height');                // size of text 
  bbt = $('.gt_table_body').css('border-top-width');     // table, head, body border (* 6)
  fss = parseInt(fs, 10);                                // strip the px from the value
  bbw = parseInt(bbt, 10);                               // strip the px from the value
  cz = sih/(sih - 11 - bbw - fss); // height of plot - margins - padding - the bottom (ticks, label, values)
  cha = ch * cz;                   // add additional height, was 1.075 before cz
  nw = siw/sih * cha;              // new width of plot
  sh.setAttribute('style', 'height: ' + cha + 'px; width: ' + nw + 'px;'); // shape container for centering
  si.setAttribute('style', 'height: ' + cha + 'px; width: ' + nw + 'px;');
  
  mm = document.querySelector('div.main-container > div.row'); // now get and set sizes for centering it all
  mc = mm.clientWidth;                                  // row width
  co = document.querySelector('.col-md-3').clientWidth; //  width of the table
  ms = (mc - nw - co)/2;                                // calc margin sizes
  mm.setAttribute('style', 'margin-left: ' + ms + 'px; margin-right: ' + ms + 'px;'); // center the content
}, 100) // you know, in case I'm slow...

```
Run Code Online (Sandbox Code Playgroud)

这就是我的 RMD 中的情况。

---
title: "Untitled"
author: "me"
date: '2022-06-08'
output: html_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = F)
library(tidyverse)
library(gt)
data(mtcars)
```

<style>
.main-container {
  max-width: unset;
}
</style>

<div class = "row">
<div class = "col-md-3">

```{r tblr}
raw_dat <- mtcars[1:15, ] %>% rownames_to_column(var = "id") %>% select(id, mpg) %>% 
  mutate(links = paste(.$id, "And <a href = 'https://www.cars.com//'>here</a>"))
tibble(
  name = raw_dat$id,
  link = paste(raw_dat$mpg, "And <a href = 'https://www.cars.com//'>here</a>")) %>%
  mutate(link = map(link, gt::html)) %>%
  gt

```

</div>

<div class = "col-md-9">

```{r pltr}
   ggplot(raw_dat, aes(factor(id, rev(id)), mpg)) +
   geom_point() +
   coord_flip() +
   theme(plot.margin = margin(0.6, unit = "cm"))
```

</div>
</div>


```{r listen,results="asis",engine="js"}
// tbl font size is 1em (assuming-- rendered 16px; the padding t/b 8px)
// do what you're told 
setTimeout(function(){  // add to buttons
  ch = document.querySelector('.col-md-3').clientHeight; // how tall is the table
  sh = document.querySelector('.col-md-9');              // pull the 2nd column for manipulation
  si = document.querySelector('img');                    // assuming there's only one plot
  sih = si.clientHeight;                                 // plot height
  siw = si.clientWidth;                                  // plot width
  fs = $('.gt_table').css('line-height');                // size of text 
  bbt = $('.gt_table_body').css('border-top-width');     // table, head, body border (* 6)
  fss = parseInt(fs, 10);                                // strip the px from the value
  bbw = parseInt(bbt, 10);                               // strip the px from the value
  cz = sih/(sih - 11 - bbw - fss); // height of plot - margins - padding - the bottom (ticks, label, values)
  cha = ch * cz;                   // add additional height, was 1.075 before cz
  nw = siw/sih * cha;              // new width of plot
  sh.setAttribute('style', 'height: ' + cha + 'px; width: ' + nw + 'px;'); // shape container for centering
  si.setAttribute('style', 'height: ' + cha + 'px; width: ' + nw + 'px;');
  
  mm = document.querySelector('div.main-container > div.row'); // now get and set sizes for centering it all
  mc = mm.clientWidth;                                  // row width
  co = document.querySelector('.col-md-3').clientWidth; //  width of the table
  ms = (mc - nw - co)/2;                                // calc margin sizes
  mm.setAttribute('style', 'margin-left: ' + ms + 'px; margin-right: ' + ms + 'px;'); // center the content
}, 100) // you know, in case I'm slow...

```
Run Code Online (Sandbox Code Playgroud)

更新

我没有意识到您希望标签在绘图和表格之间对齐。对于那个很抱歉。更新后的 JS 将创建所需的效果。

```{r listenOrElse,results="asis",engine="js"}

// do what you're told
setTimeout(function(){  // add to buttons
  ch = document.querySelector('.col-md-3').clientHeight;
  sh = document.querySelector('.col-md-9');
  si = document.querySelector('img'); // assuming there's only one!
  sih = si.clientHeight;
  siw = si.clientWidth;
  cha = ch * 1.075;   // add additional height, to account for plot padding
  nw = siw/sih * cha; // new width of plot
  console.log(ch);
  sh.style.height = cha + 'px';
  si.setAttribute('style', 'height: ' + cha + 'px; width: ' + nw + 'px; padding-top: 5px;');
}, 100) // you know, in case I'm slow...

```
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

原来写的是

col-md-3如果你想要和的精确高度col-md-9相同,你可以使用 JS。

我要指出的第一件事是max-width主容器的问题。我真的建议您取消设置或更改该值。我认为它设置为 960 像素。max-width您可以使用样式更改主容器属性。

<style>
.main-container {
  max-width: 1200px;
}
</style>
Run Code Online (Sandbox Code Playgroud)

确保列的高度相同:

```{r listenOrElse,results="asis",engine="js"}

// do what you're told
setTimeout(function(){  
  ch = document.querySelector('.col-md-3').clientHeight; // get table height
  sh = document.querySelector('.col-md-9');
  si = document.querySelector('img');                // assuming there's only one!
  sih = si.clientHeight;
  siw = si.clientWidth;
  nw = siw/sih * ch;             // new width of plot (maintain aspect-ratio)
  sh.style.height = ch + 'px';   // change height of container
                                 // change height and width of plot
  si.setAttribute('style', 'height: ' + ch + 'px; width: ' + nw + 'px');
}, 100) // you know, in case I'm slow...

```
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • @Kat 尝试使用不同数量的表行,例如“mtcars[1:5,]”、“mtcars[1:30,]”,看看它是否仍然按预期工作。根据OP:_“我想使其自动,因为对于我的实际数据,它将定期更改”_ (2认同)