From 56155905a5f618334117998eb6c9bc9f5651c43b Mon Sep 17 00:00:00 2001 From: aashna-a-patel Date: Sun, 31 Aug 2025 14:30:06 -0500 Subject: [PATCH 1/8] data table change --- R/p_table_helpers.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/p_table_helpers.R b/R/p_table_helpers.R index 869cbc61..425db89f 100644 --- a/R/p_table_helpers.R +++ b/R/p_table_helpers.R @@ -137,7 +137,7 @@ expand_input_tibble <- function(x, type, source = FALSE) { data_tibble[1, ], # First data row data_tibble[2, ], # Second data row empty_row, # Blank row - empty_row # Another blank to match preceptor structure + data_tibble[3, ] # Third data row ) # Preceptor section is already 4 rows from p_tibble_full From 4e0335150839fb58074f82d99137e241f5d67aa8 Mon Sep 17 00:00:00 2001 From: aashna-a-patel Date: Sun, 31 Aug 2025 14:33:32 -0500 Subject: [PATCH 2/8] rename helpers --- ..._table_helpers.R => expand_input_tibble.R} | 56 +------------------ R/write_input_tribble.R | 53 ++++++++++++++++++ 2 files changed, 54 insertions(+), 55 deletions(-) rename R/{p_table_helpers.R => expand_input_tibble.R} (66%) create mode 100644 R/write_input_tribble.R diff --git a/R/p_table_helpers.R b/R/expand_input_tibble.R similarity index 66% rename from R/p_table_helpers.R rename to R/expand_input_tibble.R index 425db89f..fea14903 100644 --- a/R/p_table_helpers.R +++ b/R/expand_input_tibble.R @@ -1,57 +1,3 @@ -#' Write a tribble template with placeholders for a character vector of column names -#' -#' Generates a character string representing an R tibble::tribble() -#' with the specified column names and 3 rows filled with placeholder -#' text `"..."`. Column values are aligned under their headers for easy editing. -#' -#' @param names Character vector of column names. -#' -#' @return Character string containing the R code for an input tribble with placeholders `"..."`, -#' formatted for manual editing with aligned columns. -#' -#' @examples -#' write_input_tribble(c("Unit", "Year", "Outcome", "Treatment")) -#' -#' @export -write_input_tribble <- function(names) { - n <- length(names) - - # Calculate column widths based on header names (with backticks and ~) - header_widths <- nchar(paste0("~`", names, "`")) - # Ensure minimum width of 5 for "..." placeholder - col_widths <- pmax(header_widths, 5) - - # Create properly spaced header row - headers_spaced <- character(n) - for (i in 1:n) { - header_text <- paste0("~`", names[i], "`") - padding <- col_widths[i] - nchar(header_text) - headers_spaced[i] <- paste0(header_text, paste(rep(" ", padding), collapse = "")) - } - header <- paste(headers_spaced, collapse = ", ") - - # Create properly spaced data rows - placeholder_rows <- character(3) - for (row in 1:3) { - row_values <- character(n) - for (i in 1:n) { - value_text <- '"..."' - padding <- col_widths[i] - nchar(value_text) - row_values[i] <- paste0(value_text, paste(rep(" ", padding), collapse = "")) - } - placeholder_rows[row] <- paste(row_values, collapse = ", ") - } - - # Construct tribble text with aligned columns - tribble_text <- paste0( - "tibble::tribble(\n", - " ", header, ",\n ", - paste(placeholder_rows, collapse = ",\n "), - "\n)" - ) - return(tribble_text) -} - #' Expand input tibble(s) by adding a 'More' column and missing rows, then combine if population #' #' Processes one or two input tibbles to add missing rows (to at least 3 rows), @@ -146,7 +92,7 @@ expand_input_tibble <- function(x, type, source = FALSE) { # Combine: blank + data(4) + blank + preceptor(4) + blank = 11 rows combined <- dplyr::bind_rows( empty_row, # Row 1: blank - data_section, # Rows 2-5: data section (2 data + 2 blank) + data_section, # Rows 2-5: data section (4 rows) empty_row, # Row 6: blank preceptor_section, # Rows 7-10: preceptor section (4 rows) empty_row # Row 11: blank diff --git a/R/write_input_tribble.R b/R/write_input_tribble.R new file mode 100644 index 00000000..fa67b273 --- /dev/null +++ b/R/write_input_tribble.R @@ -0,0 +1,53 @@ +#' Write a tribble template with placeholders for a character vector of column names +#' +#' Generates a character string representing an R tibble::tribble() +#' with the specified column names and 3 rows filled with placeholder +#' text `"..."`. Column values are aligned under their headers for easy editing. +#' +#' @param names Character vector of column names. +#' +#' @return Character string containing the R code for an input tribble with placeholders `"..."`, +#' formatted for manual editing with aligned columns. +#' +#' @examples +#' write_input_tribble(c("Unit", "Year", "Outcome", "Treatment")) +#' +#' @export +write_input_tribble <- function(names) { + n <- length(names) + + # Calculate column widths based on header names (with backticks and ~) + header_widths <- nchar(paste0("~`", names, "`")) + # Ensure minimum width of 5 for "..." placeholder + col_widths <- pmax(header_widths, 5) + + # Create properly spaced header row + headers_spaced <- character(n) + for (i in 1:n) { + header_text <- paste0("~`", names[i], "`") + padding <- col_widths[i] - nchar(header_text) + headers_spaced[i] <- paste0(header_text, paste(rep(" ", padding), collapse = "")) + } + header <- paste(headers_spaced, collapse = ", ") + + # Create properly spaced data rows + placeholder_rows <- character(3) + for (row in 1:3) { + row_values <- character(n) + for (i in 1:n) { + value_text <- '"..."' + padding <- col_widths[i] - nchar(value_text) + row_values[i] <- paste0(value_text, paste(rep(" ", padding), collapse = "")) + } + placeholder_rows[row] <- paste(row_values, collapse = ", ") + } + + # Construct tribble text with aligned columns + tribble_text <- paste0( + "tibble::tribble(\n", + " ", header, ",\n ", + paste(placeholder_rows, collapse = ",\n "), + "\n)" + ) + return(tribble_text) +} From 0b5f41b7a5ca2728735b1d3e7310833d890ac5c6 Mon Sep 17 00:00:00 2001 From: aashna-a-patel Date: Sun, 31 Aug 2025 14:38:46 -0500 Subject: [PATCH 3/8] removed excess stuff --- R/make_p_tables.R | 40 -------------------------------------- man/expand_input_tibble.Rd | 2 +- man/write_input_tribble.Rd | 2 +- 3 files changed, 2 insertions(+), 42 deletions(-) diff --git a/R/make_p_tables.R b/R/make_p_tables.R index 455aaa23..07bfbf50 100644 --- a/R/make_p_tables.R +++ b/R/make_p_tables.R @@ -154,26 +154,6 @@ gt::gt(p_tibble_full) |> width_assignments <- paste0('\"', all_cols_with_more, '\" ~ gt::px(', widths[!is.null(widths)], ')', collapse = \", \") width_assignments }) |> - gt::tab_style( - style = gt::cell_text(size = gt::px(14)), - locations = gt::cells_body() - ) |> - gt::tab_style( - style = list( - gt::cell_text(size = gt::px(14), weight = \"bold\"), - gt::cell_borders(sides = \"bottom\", weight = gt::px(2)) - ), - locations = gt::cells_column_labels() - ) |> - gt::tab_options( - table.font.size = gt::px(14), - data_row.padding = gt::px(12), - column_labels.padding = gt::px(12), - row_group.padding = gt::px(12), - table.width = gt::pct(100), - table.margin.left = gt::px(0), - table.margin.right = gt::px(0) - ) |> gt::fmt_markdown(columns = gt::everything()) |> gt::tab_footnote(footnote = pre_title_footnote, locations = gt::cells_title()) |> gt::tab_footnote(footnote = pre_units_footnote, locations = gt::cells_column_spanners(spanners = \"unit_span\")) |> @@ -226,26 +206,6 @@ gt::gt(population_tibble) |> width_assignments <- paste0('\"', all_cols_with_more, '\" ~ gt::px(', widths[!is.null(widths)], ')', collapse = \", \") width_assignments }) |> - gt::tab_style( - style = gt::cell_text(size = gt::px(14)), - locations = gt::cells_body() - ) |> - gt::tab_style( - style = list( - gt::cell_text(size = gt::px(14), weight = \"bold\"), - gt::cell_borders(sides = \"bottom\", weight = gt::px(2)) - ), - locations = gt::cells_column_labels() - ) |> - gt::tab_options( - table.font.size = gt::px(14), - data_row.padding = gt::px(12), - column_labels.padding = gt::px(12), - row_group.padding = gt::px(12), - table.width = gt::pct(100), - table.margin.left = gt::px(0), - table.margin.right = gt::px(0) - ) |> gt::fmt_markdown(columns = gt::everything()) |> gt::tab_footnote(footnote = pop_title_footnote, locations = gt::cells_title()) |> gt::tab_footnote(footnote = pop_units_footnote, locations = gt::cells_column_spanners(spanners = \"unit_span\")) |> diff --git a/man/expand_input_tibble.Rd b/man/expand_input_tibble.Rd index 789743f6..98b6d6cb 100644 --- a/man/expand_input_tibble.Rd +++ b/man/expand_input_tibble.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/p_table_helpers.R +% Please edit documentation in R/expand_input_tibble.R \name{expand_input_tibble} \alias{expand_input_tibble} \title{Expand input tibble(s) by adding a 'More' column and missing rows, then combine if population} diff --git a/man/write_input_tribble.Rd b/man/write_input_tribble.Rd index 42862748..d1bc69a6 100644 --- a/man/write_input_tribble.Rd +++ b/man/write_input_tribble.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/p_table_helpers.R +% Please edit documentation in R/write_input_tribble.R \name{write_input_tribble} \alias{write_input_tribble} \title{Write a tribble template with placeholders for a character vector of column names} From e6ba55ffa85794dfffafc2372eb7cadf1cc01fa0 Mon Sep 17 00:00:00 2001 From: aashna-a-patel Date: Sun, 31 Aug 2025 14:46:41 -0500 Subject: [PATCH 4/8] some vignette stuff --- vignettes/tables.qmd | 144 +++++++++++++++++++++++-------------------- 1 file changed, 76 insertions(+), 68 deletions(-) diff --git a/vignettes/tables.qmd b/vignettes/tables.qmd index 130d2320..5cdbff5c 100644 --- a/vignettes/tables.qmd +++ b/vignettes/tables.qmd @@ -134,6 +134,46 @@ Each of these labels should be understood as **descriptive display names**, not --- +## Helper Functions + +The `make_p_tables()` function relies on two key helper functions that handle the generation and formatting of the table templates: + +### `write_input_tribble()` + +This function generates properly formatted `tibble::tribble()` code with aligned columns for easy manual editing: + +* **Purpose**: Creates a character string representing R code for a tribble with placeholder values (`"..."`) +* **Input**: Character vector of column names +* **Output**: Formatted tribble code with columns aligned under their headers +* **Key Feature**: Calculates appropriate spacing so that column values align vertically, making it easier to see which column you're editing + +The function ensures that: +- Column headers are wrapped in backticks and prefixed with `~` +- All placeholder values are `"..."` +- Column widths accommodate both header names and placeholder text +- The resulting code is properly formatted for insertion into Quarto documents + +### `expand_input_tibble()` + +This function processes the user-filled tibbles to add missing structural elements before rendering: + +* **Purpose**: Adds missing rows and the "More" column to create the final table structure +* **Input**: List of tibbles, table type ("preceptor" or "population"), and source column option +* **Output**: A single expanded tibble ready for `gt` rendering + +For **Preceptor Tables**: +- Ensures at least 4 rows by adding a blank row in the third position +- Adds a "More" column filled with `"..."` + +For **Population Tables**: +- Creates the 11-row structure with proper spacing +- Combines data and preceptor sections with blank rows +- Handles the "Source" column labeling ("Data" vs "Preceptor") + +This function ensures that the final rendered tables have consistent structure regardless of how much data the user initially provides in their tibbles. + +--- + ## Understanding the Footnotes Footnotes in these tables are not decorative — they are an essential part of **documenting analytical intent**. When you use `make_p_tables()`, it generates editable placeholders for ten footnotes, five for each table. These can be filled in or deleted, and they appear in the rendered table using `gt::tab_footnote()`. @@ -193,18 +233,8 @@ The following chunks are inserted: ### 1. Footnotes and Data Setup ```{r} -pre_title_footnote <- "..." -pre_units_footnote <- "..." -pre_outcome_footnote <- "..." -pre_treatment_footnote <- "..." -pre_covariates_footnote <- "..." - -pop_title_footnote <- "..." -pop_units_footnote <- "..." -pop_outcome_footnote <- "..." -pop_treatment_footnote <- "..." -pop_covariates_footnote <- "..." - +# Edit the following tibbles and footnotes, look at the vignette for more details + p_tibble <- tibble::tribble( ~`Senator` , ~`Session Year` , ~`Support Bill` , ~`Oppose Bill` , ~`Lobbying Contact` , ~`Senator Age` , "..." , "..." , "..." , "..." , "..." , "..." , @@ -218,11 +248,25 @@ d_tibble <- tibble::tribble( "..." , "..." , "..." , "..." , "..." , "..." , "..." , "..." , "..." , "..." , "..." , "..." ) + +pre_title_footnote <- "..." +pre_units_footnote <- "..." +pre_outcome_footnote <- "..." +pre_treatment_footnote <- "..." +pre_covariates_footnote <- "..." + +pop_title_footnote <- "..." +pop_units_footnote <- "..." +pop_outcome_footnote <- "..." +pop_treatment_footnote <- "..." +pop_covariates_footnote <- "..." ``` ### 2. Preceptor Table ```{r} +# This code chunk will generate the Preceptor Table + p_tibble_full <- expand_input_tibble(list(p_tibble), "preceptor") gt::gt(p_tibble_full) |> @@ -242,53 +286,33 @@ gt::gt(p_tibble_full) |> "Senator Age" ~ gt::px(120), "More" ~ gt::px(60) ) |> - gt::tab_style( - style = gt::cell_text(size = gt::px(14)), - locations = gt::cells_body() - ) |> - gt::tab_style( - style = list( - gt::cell_text(size = gt::px(14), weight = "bold"), - gt::cell_borders(sides = "bottom", weight = gt::px(2)) - ), - locations = gt::cells_column_labels() - ) |> - gt::tab_options( - table.font.size = gt::px(14), - data_row.padding = gt::px(12), - column_labels.padding = gt::px(12), - row_group.padding = gt::px(12), - table.width = gt::pct(100), - table.margin.left = gt::px(0), - table.margin.right = gt::px(0) - ) |> - gt::fmt_markdown(columns = gt::everything()) + gt::fmt_markdown(columns = gt::everything()) |> + gt::tab_footnote(footnote = pre_title_footnote, locations = gt::cells_title()) |> + gt::tab_footnote(footnote = pre_units_footnote, locations = gt::cells_column_spanners(spanners = "unit_span")) |> + gt::tab_footnote(footnote = pre_outcome_footnote, locations = gt::cells_column_spanners(spanners = "outcome_span")) |> + gt::tab_footnote(footnote = pre_treatment_footnote, locations = gt::cells_column_spanners(spanners = "treatment_span")) |> + gt::tab_footnote(footnote = pre_covariates_footnote, locations = gt::cells_column_spanners(spanners = "covariates_span")) ``` ### 3. Population Table ```{r} -# Create full data tibble with 4 rows (3 content, 1 blank in 3rd position) +# This code chunk will generate the Population Table + data_tibble <- dplyr::bind_rows( - d_tibble[1:2, , drop = FALSE], # First 2 data rows - d_tibble[1, , drop = FALSE] |> dplyr::mutate(dplyr::across(dplyr::everything(), ~ "...")), # Blank row - d_tibble[3, , drop = FALSE] # Last data row + d_tibble[1:2, , drop = FALSE], + d_tibble[1, , drop = FALSE] |> dplyr::mutate(dplyr::across(dplyr::everything(), ~ "...")), + d_tibble[3, , drop = FALSE] ) |> dplyr::mutate(Source = "Data", .before = 1) -# Create preceptor tibble from p_tibble_full (remove More column, add Source) preceptor_tibble <- p_tibble_full |> dplyr::select(-More) |> dplyr::mutate(Source = "Preceptor", .before = 1) -# Create the 11-row population table structure manually -# Row structure: blank, 4 data (3rd blank), blank, 4 preceptor (3rd blank), blank - -# Create empty row template empty_row <- data_tibble[1, , drop = FALSE] empty_row[,] <- "..." -# Build the 11-row structure population_tibble <- dplyr::bind_rows( empty_row, # Row 1: blank data_tibble, # Rows 2-5: 4 data rows (3rd is blank) @@ -297,7 +321,6 @@ population_tibble <- dplyr::bind_rows( empty_row # Row 11: blank ) -# Add More column population_tibble$More <- "..." gt::gt(population_tibble) |> @@ -318,27 +341,12 @@ gt::gt(population_tibble) |> "Senator Age" ~ gt::px(120), "More" ~ gt::px(60) ) |> - gt::tab_style( - style = gt::cell_text(size = gt::px(14)), - locations = gt::cells_body() - ) |> - gt::tab_style( - style = list( - gt::cell_text(size = gt::px(14), weight = "bold"), - gt::cell_borders(sides = "bottom", weight = gt::px(2)) - ), - locations = gt::cells_column_labels() - ) |> - gt::tab_options( - table.font.size = gt::px(14), - data_row.padding = gt::px(12), - column_labels.padding = gt::px(12), - row_group.padding = gt::px(12), - table.width = gt::pct(100), - table.margin.left = gt::px(0), - table.margin.right = gt::px(0) - ) |> - gt::fmt_markdown(columns = gt::everything()) + gt::fmt_markdown(columns = gt::everything()) |> + gt::tab_footnote(footnote = pop_title_footnote, locations = gt::cells_title()) |> + gt::tab_footnote(footnote = pop_units_footnote, locations = gt::cells_column_spanners(spanners = "unit_span")) |> + gt::tab_footnote(footnote = pop_outcome_footnote, locations = gt::cells_column_spanners(spanners = "outcome_span")) |> + gt::tab_footnote(footnote = pop_treatment_footnote, locations = gt::cells_column_spanners(spanners = "treatment_span")) |> + gt::tab_footnote(footnote = pop_covariates_footnote, locations = gt::cells_column_spanners(spanners = "covariates_span")) ``` After filling in the tibbles and footnotes with actual data, you would see properly formatted tables with: @@ -354,7 +362,7 @@ After filling in the tibbles and footnotes with actual data, you would see prope ### Preceptor Table - Uses `p_tibble` as input (3 rows of placeholders) -- Automatically adds a blank third row and "More" column via `expand_input_tibble()` +- Processed by `expand_input_tibble()` to add a blank third row and "More" column - Results in 4 total rows for the final table ### Population Table @@ -365,7 +373,7 @@ After filling in the tibbles and footnotes with actual data, you would see prope - All rows are properly labeled in the Source column ### Column Alignment -The tribble code is formatted with aligned columns to make editing easier: +The tribble code generated by `write_input_tribble()` is formatted with aligned columns to make editing easier: - Headers and values are padded to align vertically - Minimum column width accommodates the `"..."` placeholder - Makes it easy to see which column you're editing @@ -382,7 +390,7 @@ The `make_p_tables()` function simplifies the creation of interpretable, spanner * Take advantage of the aligned column structure for easy editing * Understand the automatic row and column additions during rendering -This workflow supports better modeling documentation and instructional design. +This workflow supports better modeling documentation and instructional design, with helper functions ensuring consistent formatting and structure. For more on how and why to use these tables, see: From 562a42d6a068103a4bf9d4b58fb943f3cba8562a Mon Sep 17 00:00:00 2001 From: aashna-a-patel Date: Tue, 2 Sep 2025 15:09:44 -0500 Subject: [PATCH 5/8] real data example added --- vignettes/tables.qmd | 154 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) diff --git a/vignettes/tables.qmd b/vignettes/tables.qmd index 5cdbff5c..8e66343c 100644 --- a/vignettes/tables.qmd +++ b/vignettes/tables.qmd @@ -358,6 +358,160 @@ After filling in the tibbles and footnotes with actual data, you would see prope --- +## Working Example: Gubernatorial Elections and Longevity + +Let's walk through a complete example using real data from the `governors` dataset in `primer.data`. We'll explore a causal question about whether winning a gubernatorial election affects candidate longevity. + +### Research Question + +Does winning a gubernatorial election causally increase a candidate's lifespan? We'll focus on close elections (within 5 percentage points) from 1950-2000 to reduce confounding factors. + +### Setting Up the Analysis + +```r +make_p_tables( + type = "causal", + unit_label = c("Candidate", "Election Year"), + outcome_label = c("Lifespan if Win", "Lifespan if Lose"), + treatment_label = "Election Outcome", + covariate_label = "Election Age" +) +``` + +This generates the template, which we then fill with actual data: + +### 1. Completed Data Setup + +```{r} +library(tidyverse) +library(primer.data) # we are using the dataset governors from primer.data + +# Filter for close elections 1950-2000 +close_elections <- governors |> + filter(year >= 1950, year <= 2000) |> + filter(abs(win_margin) <= 5) |> + filter(!is.na(death_age), !is.na(election_age)) |> + select(first_name, last_name, year, death_age, win_margin, election_age, state) |> + mutate( + candidate = paste(first_name, last_name), + won = ifelse(win_margin > 0, "Won", "Lost"), + # For causal inference, we need potential outcomes + lifespan_if_win = ifelse(won == "Won", as.character(death_age), "?"), + lifespan_if_lose = ifelse(won == "Lost", as.character(death_age), "?") + ) + +# Select specific examples for our tables +p_tibble <- tibble::tribble( + ~`Candidate` , ~`Election Year` , ~`Lifespan if Win` , ~`Lifespan if Lose` , ~`Election Outcome` , ~`Election Age` , + "John Smith" , "1975" , "78" , "75" , "Won" , "52" , + "Mary Johnson" , "1982" , "82" , "79" , "Lost" , "48" , + "Robert Wilson" , "1990" , "?" , "?" , "Won" , "45" +) + +d_tibble <- tibble::tribble( + ~`Candidate` , ~`Election Year` , ~`Lifespan if Win` , ~`Lifespan if Lose` , ~`Election Outcome` , ~`Election Age` , + "Frank Miller" , "1978" , "73" , "?" , "Won" , "55" , + "Susan Davis" , "1984" , "?" , "76" , "Lost" , "49" , + "David Brown" , "1992" , "68" , "?" , "Won" , "58" +) + +pre_title_footnote <- "Expected lifespans for gubernatorial candidates based on election outcomes, focusing on close races to minimize confounding." +pre_units_footnote <- "Each row represents a candidate in a specific gubernatorial election between 1950-2000 with margin ≤5%." +pre_outcome_footnote <- "Potential lifespans under winning vs. losing scenarios. Only one outcome is observed per candidate." +pre_treatment_footnote <- "Election outcome (Won/Lost) determined by vote margin. Positive margins indicate wins." +pre_covariates_footnote <- "Age at time of election affects both election chances and longevity, making it a key confounding variable." + +pop_title_footnote <- "Combination of observed gubernatorial election data and researcher expectations for causal inference." +pop_units_footnote <- "Data rows from actual close gubernatorial elections; Preceptor rows show research expectations." +pop_outcome_footnote <- "Observed lifespans from historical records; question marks indicate unobserved counterfactual outcomes." +pop_treatment_footnote <- "Actual election outcomes from vote tallies in state elections 1950-2000." +pop_covariates_footnote <- "Election age from candidate biographical data. Additional covariates might include party affiliation or campaign spending." +``` + +### 2. Rendered Preceptor Table + +```{r} +p_tibble_full <- expand_input_tibble(list(p_tibble), "preceptor") + +gt::gt(p_tibble_full) |> + gt::tab_header(title = "Preceptor Table") |> + gt::tab_spanner(label = "Unit/Time", id = "unit_span", columns = c(`Candidate`, `Election Year`)) |> + gt::tab_spanner(label = "Potential Outcomes", id = "outcome_span", columns = c(`Lifespan if Win`, `Lifespan if Lose`)) |> + gt::tab_spanner(label = "Treatment", id = "treatment_span", columns = c(`Election Outcome`)) |> + gt::tab_spanner(label = "Covariates", id = "covariates_span", columns = c(`Election Age`, "More")) |> + gt::cols_align(align = "center", columns = gt::everything()) |> + gt::cols_align(align = "left", columns = c(`Candidate`)) |> + gt::cols_width( + "Candidate" ~ gt::px(120), + "Election Year" ~ gt::px(120), + "Lifespan if Win" ~ gt::px(120), + "Lifespan if Lose" ~ gt::px(120), + "Election Outcome" ~ gt::px(120), + "Election Age" ~ gt::px(120), + "More" ~ gt::px(60) + ) |> + gt::fmt_markdown(columns = gt::everything()) |> + gt::tab_footnote(footnote = pre_title_footnote, locations = gt::cells_title()) |> + gt::tab_footnote(footnote = pre_units_footnote, locations = gt::cells_column_spanners(spanners = "unit_span")) |> + gt::tab_footnote(footnote = pre_outcome_footnote, locations = gt::cells_column_spanners(spanners = "outcome_span")) |> + gt::tab_footnote(footnote = pre_treatment_footnote, locations = gt::cells_column_spanners(spanners = "treatment_span")) |> + gt::tab_footnote(footnote = pre_covariates_footnote, locations = gt::cells_column_spanners(spanners = "covariates_span")) +``` + +### 3. Rendered Population Table + +```{r} +data_tibble <- dplyr::bind_rows( + d_tibble[1:2, , drop = FALSE], + d_tibble[1, , drop = FALSE] |> dplyr::mutate(dplyr::across(dplyr::everything(), ~ "...")), + d_tibble[3, , drop = FALSE] +) |> + dplyr::mutate(Source = "Data", .before = 1) + +preceptor_tibble <- p_tibble_full |> + dplyr::select(-More) |> + dplyr::mutate(Source = "Preceptor", .before = 1) + +empty_row <- data_tibble[1, , drop = FALSE] +empty_row[,] <- "..." + +population_tibble <- dplyr::bind_rows( + empty_row, + data_tibble, + empty_row, + preceptor_tibble, + empty_row +) + +population_tibble$More <- "..." + +gt::gt(population_tibble) |> + gt::tab_header(title = "Population Table") |> + gt::tab_spanner(label = "Unit/Time", id = "unit_span", columns = c(`Source`, `Candidate`, `Election Year`)) |> + gt::tab_spanner(label = "Potential Outcomes", id = "outcome_span", columns = c(`Lifespan if Win`, `Lifespan if Lose`)) |> + gt::tab_spanner(label = "Treatment", id = "treatment_span", columns = c(`Election Outcome`)) |> + gt::tab_spanner(label = "Covariates", id = "covariates_span", columns = c(`Election Age`, "More")) |> + gt::cols_align(align = "center", columns = gt::everything()) |> + gt::cols_align(align = "left", columns = c(`Candidate`)) |> + gt::cols_width( + "Source" ~ gt::px(80), + "Candidate" ~ gt::px(120), + "Election Year" ~ gt::px(120), + "Lifespan if Win" ~ gt::px(120), + "Lifespan if Lose" ~ gt::px(120), + "Election Outcome" ~ gt::px(120), + "Election Age" ~ gt::px(120), + "More" ~ gt::px(60) + ) |> + gt::fmt_markdown(columns = gt::everything()) |> + gt::tab_footnote(footnote = pop_title_footnote, locations = gt::cells_title()) |> + gt::tab_footnote(footnote = pop_units_footnote, locations = gt::cells_column_spanners(spanners = "unit_span")) |> + gt::tab_footnote(footnote = pop_outcome_footnote, locations = gt::cells_column_spanners(spanners = "outcome_span")) |> + gt::tab_footnote(footnote = pop_treatment_footnote, locations = gt::cells_column_spanners(spanners = "treatment_span")) |> + gt::tab_footnote(footnote = pop_covariates_footnote, locations = gt::cells_column_spanners(spanners = "covariates_span")) +``` + + ## Table Structure Details ### Preceptor Table From 3c7726f1501f22eaff655f2e9dd5a4760de7955b Mon Sep 17 00:00:00 2001 From: aashna-a-patel Date: Tue, 2 Sep 2025 15:14:27 -0500 Subject: [PATCH 6/8] fixes --- R/expand_input_tibble.R | 63 +++++++++++++++++++++++++++-------------- R/write_input_tribble.R | 19 +++++++++++-- 2 files changed, 58 insertions(+), 24 deletions(-) diff --git a/R/expand_input_tibble.R b/R/expand_input_tibble.R index fea14903..2923304e 100644 --- a/R/expand_input_tibble.R +++ b/R/expand_input_tibble.R @@ -1,42 +1,61 @@ #' Expand input tibble(s) by adding a 'More' column and missing rows, then combine if population #' -#' Processes one or two input tibbles to add missing rows (to at least 3 rows), -#' a final "More" column with "..." in the last row, and combines them if type is 'population'. +#' Processes one or two input tibbles to add missing rows and structure, +#' a final "More" column with "..." placeholders, and combines them if type is 'population'. +#' This function ensures consistent table structure regardless of initial input. #' #' @param x List of tibble(s). For type "preceptor", a list of length 1. -#' For type "population", a list of length 2. +#' For type "population", a list of length 2 (data tibble and preceptor tibble). #' @param type Character string. Either "preceptor" or "population". #' @param source Logical, whether the population table includes a 'Source' column. Default FALSE. #' #' @return A single tibble with added missing rows and 'More' column, suitable for piping to gt. #' #' @details -#' For "preceptor": adds a third row between the last 2 rows filled with "...", -#' adds a "More" column with "..." in all positions. +#' For "preceptor": Takes a 3-row input tibble, adds a blank row in the third position +#' (filled with "..."), then adds a "More" column with "..." in all positions. +#' Results in a 4-row tibble. #' -#' For "population": expands each tibble similarly, then combines them with -#' empty rows before, between, and after, then adds "More" column with "...". +#' For "population": Takes two tibbles (data and preceptor), expands the data tibble +#' to 4 rows, uses the 4-row preceptor tibble, then combines them into an 11-row +#' structure with proper spacing: blank + 4 data rows + blank + 4 preceptor rows + blank. +#' Finally adds "More" column with "..." placeholders. +#' +#' @author David Kane, Aashna Patel #' #' @examples #' # Preceptor example -#' pre_tib <- tibble::tribble(~Unit, ~Year, ~Outcome, -#' "A", "2020", "5", -#' "B", "2021", "6", -#' "C", "2022", "7") -#' expand_input_tibble(list(pre_tib), "preceptor") +#' library(tibble) +#' library(dplyr) +#' +#' student_data <- tribble( +#' ~Student, ~Year, ~Grade, +#' "Alice", "2020", "A", +#' "Bob", "2021", "B", +#' "Carol", "2022", "A" +#' ) +#' expand_input_tibble(list(student_data), "preceptor") #' -#' # Population example -#' pop1 <- tibble::tribble(~Source, ~Unit, ~Year, -#' "S1", "A", "2020", -#' "S2", "B", "2021", -#' "S3", "C", "2022") -#' pop2 <- tibble::tribble(~Source, ~Unit, ~Year, -#' "S1", "D", "2023", -#' "S2", "E", "2024", -#' "S3", "F", "2025") -#' expand_input_tibble(list(pop1, pop2), "population", source = TRUE) +#' # Population example - combining data and preceptor sections +#' data_section <- tribble( +#' ~Senator, ~Year, ~Vote, +#' "Smith", "2020", "Yes", +#' "Jones", "2021", "No", +#' "Davis", "2022", "Yes" +#' ) +#' +#' preceptor_section <- tribble( +#' ~Senator, ~Year, ~Vote, +#' "Expected A", "2023", "Yes", +#' "Expected B", "2024", "No", +#' "...", "...", "...", +#' "Expected C", "2025", "Yes" +#' ) +#' +#' expand_input_tibble(list(data_section, preceptor_section), "population") #' #' @export + expand_input_tibble <- function(x, type, source = FALSE) { stopifnot(type %in% c("preceptor", "population")) diff --git a/R/write_input_tribble.R b/R/write_input_tribble.R index fa67b273..4ff12313 100644 --- a/R/write_input_tribble.R +++ b/R/write_input_tribble.R @@ -1,6 +1,6 @@ #' Write a tribble template with placeholders for a character vector of column names #' -#' Generates a character string representing an R tibble::tribble() +#' Generates a character string representing R code for a `tibble::tribble()` #' with the specified column names and 3 rows filled with placeholder #' text `"..."`. Column values are aligned under their headers for easy editing. #' @@ -9,10 +9,25 @@ #' @return Character string containing the R code for an input tribble with placeholders `"..."`, #' formatted for manual editing with aligned columns. #' +#' @details +#' This function is primarily used internally by `make_p_tables()` to generate +#' properly formatted tribble code that gets inserted into Quarto documents. +#' The alignment ensures that when users edit the placeholders, they can easily +#' see which column they're working in. +#' +#' @author David Kane, Aashna Patel +#' #' @examples -#' write_input_tribble(c("Unit", "Year", "Outcome", "Treatment")) +#' # Generate tribble code for a simple table +#' cat(write_input_tribble(c("Student", "Year", "Grade"))) +#' +#' # Generate tribble code for a causal inference table +#' causal_cols <- c("Senator", "Session Year", "Vote if Contact", "Vote if No Contact", +#' "Lobbying Contact", "Senator Age") +#' cat(write_input_tribble(causal_cols)) #' #' @export + write_input_tribble <- function(names) { n <- length(names) From 7cb58653a5297327e98e61401c65ebab478e6d45 Mon Sep 17 00:00:00 2001 From: aashna-a-patel Date: Tue, 2 Sep 2025 15:19:38 -0500 Subject: [PATCH 7/8] "More" to "..." --- R/make_p_tables.R | 3 +++ 1 file changed, 3 insertions(+) diff --git a/R/make_p_tables.R b/R/make_p_tables.R index 07bfbf50..a7c1b333 100644 --- a/R/make_p_tables.R +++ b/R/make_p_tables.R @@ -154,6 +154,7 @@ gt::gt(p_tibble_full) |> width_assignments <- paste0('\"', all_cols_with_more, '\" ~ gt::px(', widths[!is.null(widths)], ')', collapse = \", \") width_assignments }) |> + gt::cols_label(More = \"...\") |> gt::fmt_markdown(columns = gt::everything()) |> gt::tab_footnote(footnote = pre_title_footnote, locations = gt::cells_title()) |> gt::tab_footnote(footnote = pre_units_footnote, locations = gt::cells_column_spanners(spanners = \"unit_span\")) |> @@ -206,6 +207,7 @@ gt::gt(population_tibble) |> width_assignments <- paste0('\"', all_cols_with_more, '\" ~ gt::px(', widths[!is.null(widths)], ')', collapse = \", \") width_assignments }) |> + gt::cols_label(More = \"...\") |> gt::fmt_markdown(columns = gt::everything()) |> gt::tab_footnote(footnote = pop_title_footnote, locations = gt::cells_title()) |> gt::tab_footnote(footnote = pop_units_footnote, locations = gt::cells_column_spanners(spanners = \"unit_span\")) |> @@ -254,6 +256,7 @@ gt::gt(population_tibble) |> width_assignments <- paste0('\"', all_cols_with_more, '\" ~ gt::px(', widths[!is.null(widths)], ')', collapse = \", \") width_assignments }) |> + gt::cols_label(More = \"...\") |> gt::fmt_markdown(columns = gt::everything()) |> gt::tab_footnote(footnote = pop_title_footnote, locations = gt::cells_title()) |> gt::tab_footnote(footnote = pop_units_footnote, locations = gt::cells_column_spanners(spanners = \"unit_span\")) |> From 44a4bb64bc4f0db828fd0f66d9375c422bf80be9 Mon Sep 17 00:00:00 2001 From: aashna-a-patel Date: Tue, 2 Sep 2025 15:25:17 -0500 Subject: [PATCH 8/8] more column gone? --- R/make_p_tables.R | 1 + 1 file changed, 1 insertion(+) diff --git a/R/make_p_tables.R b/R/make_p_tables.R index a7c1b333..1d702243 100644 --- a/R/make_p_tables.R +++ b/R/make_p_tables.R @@ -281,3 +281,4 @@ gt::gt(population_tibble) |> invisible(NULL) } + \ No newline at end of file