Using Highcharter in TidyTuesday CEOs departures
2021 - Week 18
By Jesús Vélez in R rstats TidyTuesday dataviz
May 1, 2021
CEO departures
The data this week comes from Gentry et al. by way of DataIsPlural.
We introduce an open‐source dataset documenting the reasons for CEO departure in S&P 1500 firms from 2000 through 2018. In our dataset, we code for various forms of voluntary and involuntary departure. We compare our dataset to three published datasets in the CEO succession literature to assess both the qualitative and quantitative differences among them and to explore how these differences impact empirical findings associated with the performance‐CEO dismissal relationship. The dataset includes eight different classifications for CEO turnover, a narrative description of each departure event, and links to sources used in constructing the narrative so that future researchers can validate or adapt the coding. The resulting data are available at ( https://doi.org/10.5281/zenodo.4543893).
This revision includes potentially relevant 8k filings from 270 days before and after the CEO’s departure date. These filings were not all useful for understanding the departure, but might be useful in general.
Another article from investors.com.
Libraries
library(tidyverse)
library(tidytext)
library(tidytuesdayR)
library(stopwords)
library(widgetframe)
library(highcharter)
Download data
tuesday_data <- tt_load(x = 2021, week = 18)
Extract data to use
A full description of the data can be found here.
departures <- tuesday_data$departures %>%
glimpse()
## Rows: 9,423
## Columns: 19
## $ dismissal_dataset_id <dbl> 559043, 12, 13, 31, 43, 51, 61, 63, 62, 65, 75, 7…
## $ coname <chr> "SONICBLUE INC", "AMERICAN AIRLINES GROUP INC", "…
## $ gvkey <dbl> 27903, 1045, 1045, 1078, 1161, 1177, 1194, 1194, …
## $ fyear <dbl> 2002, 1997, 2002, 1998, 2001, 1997, 1993, 1997, 1…
## $ co_per_rol <dbl> -1, 1, 3, 6, 11, 16, 21, 22, 24, 28, 33, 34, 38, …
## $ exec_fullname <chr> "L. Gregory Ballard", "Robert L. Crandall", "Dona…
## $ departure_code <dbl> 7, 5, 3, 5, 5, 5, 5, 7, 9, 5, 5, 5, 3, 5, 5, 3, 3…
## $ ceo_dismissal <dbl> 0, 0, 1, 0, 0, 0, 0, 0, NA, 0, 0, 0, 1, 0, 0, 1, …
## $ interim_coceo <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ tenure_no_ceodb <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
## $ max_tenure_ceodb <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
## $ fyear_gone <dbl> 2003, 1998, 2003, 1998, 2002, 1997, 1993, 1998, 1…
## $ leftofc <dttm> 2003-03-21, 1998-05-20, 2003-04-24, 1998-12-31, …
## $ still_there <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ notes <chr> "Ballard took over when the outgoing CEO said tha…
## $ sources <chr> "https://www.wsj.com/articles/SB10288576921909334…
## $ eight_ks <chr> "https://www.sec.gov/Archives/edgar/data/850519/0…
## $ cik <dbl> 850519, 6201, 6201, 1800, 2488, 1122304, 771667, …
## $ `_merge` <chr> "matched (3)", "matched (3)", "matched (3)", "mat…
General preprocessing
In particular, for this week of #TidyTuesday, I decided to focus on three main variables:
fyear
: The fiscal year in which the event occurred.departure_code
: The departure reason coded.- Involuntary - CEO death
- Involuntary - CEO illness
- Involuntary - CEO dismissed for job performance
- Involuntary - CEO dismissed for legal violations or concerns
- Voluntary - CEO retired
- Voluntary - New opportunity (new career driven succession)
- Other
- Missing
- Execucomp error
notes
: Long-form description and justification for the coding scheme assignment.
Although death and illness are correctly classified as involuntary departures,
departures due to job performance or violation of the law are, in general, the
product of the individual himself. Therefore, I decided to separate them. For
simplicity, I kept exit codes 3 and 4 as Involuntary
and the rest as Other
.
departures_processed <- departures %>%
select(fyear, departure_code, notes) %>%
filter(
departure_code < 9,
fyear > 1995,
fyear < 2019
) %>%
mutate(
involuntary = if_else(
condition = departure_code %in% 3:4,
true = "Involuntary",
false = "Other"
),
departure_code = fct_recode(
.f = factor(departure_code),
"Death" = "1",
"Illness" = "2",
"Job performance" = "3",
"Legal violations or concerns" = "4",
"Retired" = "5",
"New opportunity" = "6",
"Other" = "7",
"Missing" = "8"
)
) %>%
glimpse()
## Rows: 6,942
## Columns: 4
## $ fyear <dbl> 2002, 1997, 2002, 1998, 2001, 1997, 1997, 2000, 2007, 2…
## $ departure_code <fct> Other, Retired, Job performance, Retired, Retired, Reti…
## $ notes <chr> "Ballard took over when the outgoing CEO said that the …
## $ involuntary <chr> "Other", "Other", "Involuntary", "Other", "Other", "Oth…
Create custom credits for plots
Since I needed to generate multiple plots, I did not want to repeat myself and decided to include the process of adding credits with my brand in one place.
load = JS(" ... ")
section is not necessary in certain places.
However, I decided to use it since in this blog the iframes
that will be
generated will try to open content within itself and will throw a error.
In this way, I ensure that target
is always a new tab. 🧐👉👈
add_custom_credits <- function(hc) {
hc_credits(
hc = hc,
text = "<b>Dataviz by:</b> @jvelezmagic",
href = "https://twitter.com/jvelezmagic",
enabled = TRUE
) %>%
hc_chart(
events = list(
load = JS("
function() {
this.credits.element.onclick = function() {
window.open('https://twitter.com/jvelezmagic', '__blank');
}
}
"
)
)
)
}
CEOs departures
The first thing I wanted to find out was how the number of CEO exits changes over
time. In addition, I wanted to separate the counts into two main categories,
Involuntary
and Other
. Where involuntary would represent those CEOs who were
fired for reasons of job performance or for non-compliance with the law.
Prepare data for plot
Using the tidyverse ecosystem, answering that question boils down to using the
count()
function specifying the variables by which we want to group and count.
involuntary_departures <- departures_processed %>%
count(fyear, involuntary) %>%
glimpse()
## Rows: 46
## Columns: 3
## $ fyear <dbl> 1996, 1996, 1997, 1997, 1998, 1998, 1999, 1999, 2000, 2000…
## $ involuntary <chr> "Involuntary", "Other", "Involuntary", "Other", "Involunta…
## $ n <int> 42, 273, 52, 274, 42, 305, 58, 332, 78, 286, 64, 165, 73, …
Create interactive line plot
Having our data ready, the next thing is to use hchart()
to specify what type
of chart we want to obtain. In this case, a line graph, where each line
represents those CEO departures, either involuntary
or for other
reasons.
To help compare both groups I decided to add a shared tooltip between both lines
with hc_tooltip()
.
To help put the data in context a bit, I decided to add a band along the X axis
representing the 2008 financial crisis by specifying the plotBandas
attribute
within hc_xAxis()
.
Finally I added the credits and used frameWidget()
to allow me to display this
graphic within this static page. Inside a Rmarkdown or a Shiny app it might
not be necessary. 😬
involuntary_departures %>%
# Plot specifications -----------------------------------------------------
hchart(
type = "line",
hcaes(x = fyear, y = n, group = involuntary),
regression = TRUE
) %>%
hc_add_dependency("plugins/highcharts-regression.js") %>%
hc_tooltip(
crosshairs = TRUE,
shared = TRUE
) %>%
# Text annotations --------------------------------------------------------
hc_title(
text = "CEOs departures"
) %>%
hc_xAxis(
title = list(text = "Year"),
plotBands = list(
list(
label = list(
text = "Global<br>crisis",
style = list(
color = "white",
fontWeight = "bold"
),
useHTML = TRUE
),
color = "rgba(256,0,0,0.4)",
fillOpacity = 0.5,
from = 2006,
to = 2008
)
)
) %>%
hc_yAxis(
title = list(text = "Number of CEOs departures")
) %>%
# Credits -----------------------------------------------------------------
add_custom_credits() %>%
# Display as iframe -------------------------------------------------------
frameWidget()
Historical CEOs departures by category
I wondered how all CEOs are distributed collectively in the data by their
departure code. Here I had many display options, bars
, sunburst
, treemap
,
among others.
Choosing a visualization that allows you to see exactly what you need without
worrying about the details is important. In my case, I just wanted to make
treemaps
for fun, but I could make any other.
treemaps
can be useful when:
- You want to observe relationships among a large number of categories.
- Precision in comparisons is not that important.
- Your data is hierarchical.
In my case, I did not consider precise comparisons between categories important
at this point in the data exploration. The treemap
allowed me to quickly
determine how CEOs departures codes were distributed.
Prepare data for plot
In order for highcharter
to understand our data, we must transform it to a list
containing which objects are parents and which are children, which in javascript
could be a JSON
or dictionary
.
To solve this, highcharter
provides data_to_hierarchical()
shortcut that
allows you to directly obtain the format needed to create a treemap
or a
sunburst
. 😋✨
departures_treemap_plot <- departures_processed %>%
mutate(
fyear = as.character(fyear),
value = 1
) %>%
data_to_hierarchical(
group_vars = c(departure_code, fyear),
size_var = value
)
departures_treemap_plot[[100]] %>%
glimpse()
## List of 5
## $ name : chr "2018"
## $ id : chr "legal_violations_or_concerns_2018"
## $ parent: chr "legal_violations_or_concerns"
## $ value : num 8
## $ level : int 2
Create nested treemap
First I defined that the type of visualization I wanted was a treemap
.
The global call to dataLabels
says that, by default, don’t paint any labels in
sight. This will allow customizing the order of appearance of our labels in each
hierarchical layer.
Besides, I decided to add a bit of a separating border width between each of my categories to make it more apparent where each one started and ended.
Parameter allowDrillToNode
allows you to click on a point and access to the
next hierarchical level of the data. In our case, we only have two levels,
departures_code
and fyear
, but they could be more. 🤓
# Plot specification --------------------------------------------------------
hchart(
departures_treemap_plot,
type = "treemap",
## Global configuration ---------------------------------------------------
dataLabels = list(
enabled = FALSE
),
## Modify levels appearance -----------------------------------------------
allowDrillToNode = TRUE,
levelIsConstant = FALSE,
levels = list(
list(
level = 1,
borderWidth = 4,
dataLabels = list(
enabled = TRUE,
style = list(
fontSize = "14px"
)
)
),
list(
level = 2,
dataLabels = list(
enabled = FALSE
),
colorVariation = list(
key = "brightness",
to = 0.25
)
)
)
) %>%
# Text annotations --------------------------------------------------------
hc_title(
text = "CEOs departures by category"
) %>%
# Credits -----------------------------------------------------------------
add_custom_credits() %>%
# Display as iframe -------------------------------------------------------
frameWidget()
Why CEOs leave the company?
Once I learned how CEO departures were historically, I wondered why they had to quit. What bad things did they do? What did they get sick from? Did they have good recommendations to migrate to a better job?
To answer the questions, I decided to do some simple natural language processing like data exploration, but this could be more complicated to get better results. It all depends on what you want to achieve in the end. 🧐
Text processing
I decided to start by separating all the notes written about CEO exits to their
corresponding word form with unnest_tokens()
. This generated me a new column
called word
.
Sometimes when we write texts, not all words are important. Perhaps we could focus on certain phrases ignoring, for example, articles, pronouns, prepositions, etc.
get_stopwords()
returns a tibble with two columns, word
and lexicon
,
where word represents the stop words of a language (by default English) and
lexicon as the source from which they were extracted. Since the our data and the
data generated by get_stopwords()
contain the word
column, I performed an
anti_join()
of the tables to remove all those words that it did not require.
Following the same logic described above, I made an inner_join()
to keep
only those words that were associated with some feeling given a lexicon.
This certainly narrowed my corpus, but for my mental question it worked to
filter my observations instead of taking the global tops.
Although, perhaps to build a model you might prefer to keep all the words and
use ngrams
.
Finally, I counted the words by departure code. 😴
departures_words <- departures_processed %>%
select(departure_code, notes) %>%
unnest_tokens(output = word, input = notes) %>%
anti_join(y = get_stopwords()) %>%
inner_join(y = get_sentiments(lexicon = "bing")) %>%
count(departure_code, word) %>%
glimpse()
## Rows: 2,599
## Columns: 3
## $ departure_code <fct> Death, Death, Death, Death, Death, Death, Death, Death,…
## $ word <chr> "absence", "affluence", "attack", "best", "cancer", "ce…
## $ n <int> 1, 1, 6, 1, 11, 1, 2, 3, 1, 8, 1, 51, 1, 1, 2, 1, 1, 1,…
Prepare data for plot
I wanted to develop a word cloud where the first categories tell us how many words associated with feelings we find per category. After clicking on any of these, I wanted to show the word cloud of the words associated with those categories.
First, I used group_nest()
to create a tibble with two columns,
departure_code
and data
. I added an id
column that will be the one that
connects our charts by level. type
column will tell highcharter
that the
subplot I want is a word cloud as well.
The first call to map()
corresponds to creating two new columns to the data of
our data
column; name
and weight
, parameters described in the creation of
a wordcloud
type chart. The second call to map()
is to convert each tibble
into a highcharter-understandable list.
Finally, I counted how many words each category contained. It should be noted
that this new column n
now exists both at the first and second levels, that is,
within data
, therefore we can use it to customize our tooltips
with a better
message. 🤫
departures_words_plot <- departures_words %>%
group_nest(departure_code) %>%
mutate(
id = departure_code,
type = "wordcloud",
data = map(data, mutate, name = word, weight = log(n)),
data = map(data, list_parse),
n = lengths(data)
) %>%
glimpse()
## Rows: 8
## Columns: 5
## $ departure_code <fct> Death, Illness, Job performance, Legal violations or co…
## $ data <list> [["absence", 1, "absence", 0], ["affluence", 1, "afflu…
## $ id <fct> Death, Illness, Job performance, Legal violations or co…
## $ type <chr> "wordcloud", "wordcloud", "wordcloud", "wordcloud", "wo…
## $ n <int> 54, 94, 790, 263, 686, 76, 602, 34
Create interactive Word Cloud
First I defined that the type of chart I wanted was a wordcloud
.
Then I specified which columns to take the data from, similar to creating a
graph with ggplot2
. The drilldown
parameter is who will say where to zoom to
our data. 😉
With hc_drilldown()
we will define the series
or subplots that we want to
visualize. As you may have been imagining, we could add different levels with
different graphics, for example going from a representation of bars
to one of
lines
simply by configuring the formats of our series. 🤯
Finally I set up the texts of the figure, specifying that, when it will enter
the first level, the title will be updated and put the corresponding one for the
category. Just to keep us in context of which words are from which category.
On the other hand, I indicated that the tooltip
will show the value of the
variable n
, present at level 1 and 2 of the data. Therefore, despite displaying
the data on a logarithmic scale, we can display the absolute counts that are easier
to interpret. 😬
departures_words_plot %>%
# Plot specification ------------------------------------------------------
## First level ------------------------------------------------------------
hchart(
type = "wordcloud",
name = "Categories",
hcaes(
name = departure_code,
weight = log(n),
drilldown = departure_code
)
) %>%
## Second level -----------------------------------------------------------
hc_drilldown(
allowPointDrilldown = TRUE,
series = list_parse(departures_words_plot)
) %>%
# Text annotations --------------------------------------------------------
## Main title -------------------------------------------------------------
hc_title(
text = "CEOs, You are fired! But wait ... why?"
) %>%
hc_subtitle(
text = "Click to drill down"
) %>%
## Insert and remove title when drilldown ---------------------------------
hc_chart(
type = "column",
events = list(
drilldown = JS("
function(e) {
this.update(
{
title: {
text: e.seriesOptions.id
}
}
)
}
"
),
drillup = JS("
function() {
this.update(
{
title: {
text: 'CEOs, You are fired! But wait ... why?'
}
}
)
}
"
)
)
) %>%
## Configure how tooltip is displayed -------------------------------------
hc_tooltip(
pointFormat = tooltip_table(
x = c("Word count: "),
y = c("{point.n}")
),
useHTML = TRUE
) %>%
# Credits ---------------------------------------------------------------
add_custom_credits() %>%
# Display as iframe -----------------------------------------------------
frameWidget()
Session info
Show/hide
## ─ Session info ───────────────────────────────────────────────────────────────
## setting value
## version R version 4.0.5 (2021-03-31)
## os macOS Big Sur 10.16
## system x86_64, darwin17.0
## ui X11
## language (EN)
## collate en_US.UTF-8
## ctype en_US.UTF-8
## tz America/Mexico_City
## date 2021-05-02
##
## ─ Packages ───────────────────────────────────────────────────────────────────
## ! package * version date lib source
## P assertthat 0.2.1 2019-03-21 [?] CRAN (R 4.0.2)
## P backports 1.2.1 2020-12-09 [?] CRAN (R 4.0.2)
## P blogdown 1.3 2021-04-14 [?] CRAN (R 4.0.2)
## P bookdown 0.22 2021-04-22 [?] CRAN (R 4.0.2)
## P broom 0.7.6 2021-04-05 [?] CRAN (R 4.0.2)
## P bslib 0.2.4 2021-01-25 [?] CRAN (R 4.0.2)
## P cellranger 1.1.0 2016-07-27 [?] CRAN (R 4.0.2)
## P cli 2.5.0 2021-04-26 [?] CRAN (R 4.0.2)
## P colorspace 2.0-0 2020-11-11 [?] CRAN (R 4.0.2)
## P crayon 1.4.1 2021-02-08 [?] CRAN (R 4.0.2)
## P curl 4.3.1 2021-04-30 [?] CRAN (R 4.0.5)
## P data.table 1.14.0 2021-02-21 [?] CRAN (R 4.0.2)
## P DBI 1.1.1 2021-01-15 [?] CRAN (R 4.0.2)
## P dbplyr 2.1.1 2021-04-06 [?] CRAN (R 4.0.2)
## P digest 0.6.27 2020-10-24 [?] CRAN (R 4.0.2)
## P dplyr * 1.0.5 2021-03-05 [?] CRAN (R 4.0.2)
## P ellipsis 0.3.2 2021-04-29 [?] CRAN (R 4.0.5)
## P evaluate 0.14 2019-05-28 [?] CRAN (R 4.0.1)
## P fansi 0.4.2 2021-01-15 [?] CRAN (R 4.0.2)
## P forcats * 0.5.1 2021-01-27 [?] CRAN (R 4.0.2)
## P fs 1.5.0 2020-07-31 [?] CRAN (R 4.0.2)
## P generics 0.1.0 2020-10-31 [?] CRAN (R 4.0.2)
## P ggplot2 * 3.3.3 2020-12-30 [?] CRAN (R 4.0.2)
## P glue 1.4.2 2020-08-27 [?] CRAN (R 4.0.2)
## P gtable 0.3.0 2019-03-25 [?] CRAN (R 4.0.2)
## P haven 2.4.1 2021-04-23 [?] CRAN (R 4.0.2)
## P highcharter * 0.8.2 2020-07-26 [?] CRAN (R 4.0.2)
## P hms 1.0.0 2021-01-13 [?] CRAN (R 4.0.2)
## P htmltools 0.5.1.1 2021-01-22 [?] CRAN (R 4.0.2)
## P htmlwidgets * 1.5.3 2020-12-10 [?] CRAN (R 4.0.2)
## P httr 1.4.2 2020-07-20 [?] CRAN (R 4.0.2)
## P igraph 1.2.6 2020-10-06 [?] CRAN (R 4.0.2)
## P janeaustenr 0.1.5 2017-06-10 [?] CRAN (R 4.0.2)
## P jquerylib 0.1.4 2021-04-26 [?] CRAN (R 4.0.2)
## P jsonlite 1.7.2 2020-12-09 [?] CRAN (R 4.0.2)
## P knitr 1.33 2021-04-24 [?] CRAN (R 4.0.2)
## P lattice 0.20-41 2020-04-02 [?] CRAN (R 4.0.5)
## P lifecycle 1.0.0 2021-02-15 [?] CRAN (R 4.0.2)
## P lubridate 1.7.10 2021-02-26 [?] CRAN (R 4.0.2)
## P magrittr 2.0.1 2020-11-17 [?] CRAN (R 4.0.2)
## P Matrix 1.3-2 2021-01-06 [?] CRAN (R 4.0.5)
## P modelr 0.1.8 2020-05-19 [?] CRAN (R 4.0.2)
## P munsell 0.5.0 2018-06-12 [?] CRAN (R 4.0.2)
## P pillar 1.6.0 2021-04-13 [?] CRAN (R 4.0.4)
## P pkgconfig 2.0.3 2019-09-22 [?] CRAN (R 4.0.2)
## P purrr * 0.3.4 2020-04-17 [?] CRAN (R 4.0.2)
## P quantmod 0.4.18 2020-12-09 [?] CRAN (R 4.0.2)
## P R6 2.5.0 2020-10-28 [?] CRAN (R 4.0.2)
## P Rcpp 1.0.6 2021-01-15 [?] CRAN (R 4.0.2)
## P readr * 1.4.0 2020-10-05 [?] CRAN (R 4.0.2)
## P readxl 1.3.1 2019-03-13 [?] CRAN (R 4.0.2)
## P renv 0.13.2 2021-03-30 [?] CRAN (R 4.0.4)
## P reprex 2.0.0 2021-04-02 [?] CRAN (R 4.0.2)
## P rlang 0.4.11 2021-04-30 [?] CRAN (R 4.0.5)
## P rlist 0.4.6.1 2016-04-04 [?] CRAN (R 4.0.2)
## P rmarkdown 2.7 2021-02-19 [?] CRAN (R 4.0.2)
## P rstudioapi 0.13 2020-11-12 [?] CRAN (R 4.0.2)
## P rvest 1.0.0 2021-03-09 [?] CRAN (R 4.0.2)
## P sass 0.3.1 2021-01-24 [?] CRAN (R 4.0.2)
## P scales 1.1.1 2020-05-11 [?] CRAN (R 4.0.2)
## P selectr 0.4-2 2019-11-20 [?] CRAN (R 4.0.2)
## P sessioninfo 1.1.1 2018-11-05 [?] CRAN (R 4.0.2)
## P SnowballC 0.7.0 2020-04-01 [?] CRAN (R 4.0.2)
## P stopwords * 2.2 2021-02-10 [?] CRAN (R 4.0.2)
## P stringi 1.5.3 2020-09-09 [?] CRAN (R 4.0.2)
## P stringr * 1.4.0 2019-02-10 [?] CRAN (R 4.0.2)
## P tibble * 3.1.1 2021-04-18 [?] CRAN (R 4.0.2)
## P tidyr * 1.1.3 2021-03-03 [?] CRAN (R 4.0.2)
## P tidyselect 1.1.1 2021-04-30 [?] CRAN (R 4.0.5)
## P tidytext * 0.3.1 2021-04-10 [?] CRAN (R 4.0.2)
## P tidytuesdayR * 1.0.1 2020-07-10 [?] CRAN (R 4.0.2)
## P tidyverse * 1.3.1 2021-04-15 [?] CRAN (R 4.0.2)
## P tokenizers 0.2.1 2018-03-29 [?] CRAN (R 4.0.2)
## P TTR 0.24.2 2020-09-01 [?] CRAN (R 4.0.2)
## P usethis 2.0.1 2021-02-10 [?] CRAN (R 4.0.2)
## P utf8 1.2.1 2021-03-12 [?] CRAN (R 4.0.2)
## P vctrs 0.3.8 2021-04-29 [?] CRAN (R 4.0.5)
## P widgetframe * 0.3.1 2017-12-20 [?] CRAN (R 4.0.2)
## P withr 2.4.2 2021-04-18 [?] CRAN (R 4.0.2)
## P xfun 0.22 2021-03-11 [?] CRAN (R 4.0.2)
## P xml2 1.3.2 2020-04-23 [?] CRAN (R 4.0.2)
## P xts 0.12.1 2020-09-09 [?] CRAN (R 4.0.2)
## P yaml 2.2.1 2020-02-01 [?] CRAN (R 4.0.2)
## P zoo 1.8-9 2021-03-09 [?] CRAN (R 4.0.2)
##
## [1] /Users/jvelezmagic/Documents/Github/personal_projects/jvelezmagic/renv/library/R-4.0/x86_64-apple-darwin17.0
## [2] /private/var/folders/bt/17212s6j0xxfjty0f77xmfq00000gn/T/RtmpafrI0H/renv-system-library
##
## P ── Loaded and on-disk path mismatch.
Details
- Posted on:
- May 1, 2021
- Length:
- 17 minute read, 3537 words
- Categories:
- R rstats TidyTuesday dataviz
- See Also: