diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..5d904a9 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,74 @@ +# Claude Code Assistant Instructions + +## Project Overview +This is the forestly R package, which creates interactive forest plots for clinical trial data analysis. The package is built on top of metalite and metalite.ae packages and uses reactable for interactive tables with Plotly.js for interactive visualizations. + +## Development Guidelines + +### Testing +- load project using `devtools::load_all()` +- Run tests using: `devtools::test()` +- Run specific test files using: `devtools::test(filter = "filename")` +- Before running tests, ensure required packages are installed (metalite, metalite.ae, reactable, reactR) + +### Code Style +- Follow tidyverse style guide +- Use `|>` pipe operator (R 4.1+) +- Functions should handle both character vectors and factors robustly + +### Key Functions +- `ae_forestly()`: Main function to create interactive forest plots +- `format_ae_forestly()`: Formats AE data and configures Plotly visualizations +- `format_ae_listing()`: Formats AE listing data +- `sparkline_point_js()`: Generates JavaScript/Plotly code for interactive sparkline plots +- `propercase()`: Converts strings to proper case (handles factors) +- `titlecase()`: Converts strings to title case using tools::toTitleCase (handles factors) + +### Before Committing +- Run linting: Check for any linting issues in the IDE +- Run tests: `devtools::test()` to ensure all tests pass +- Check documentation: `devtools::document()` if roxygen comments are updated + +### Branch Strategy +- Main branch: `main` +- Feature branches: Use descriptive names like `fix-factor-handling` or `add-new-feature` +- Always create pull requests for merging into main + +### Common Commands +```r +# Load all functions for development +devtools::load_all() + +# Run all tests +devtools::test() + +# Check package +devtools::check() + +# Build documentation +devtools::document() +``` + +## Package Dependencies +- metalite +- metalite.ae +- reactable +- reactR +- plotly (via JavaScript integration) +- brew (for template processing) +- tools (base R) + +## Testing Data +The package includes test data in `data/`: +- forestly_adae.rda +- forestly_adae_3grp.rda +- forestly_adsl.rda +- forestly_adsl_3grp.rda + +## Notes for Future Development +- The `ae_listing.R` file contains functions that handle factor inputs, which was a recent fix +- Test files should use `devtools::load_all()` or source the R files directly for testing +- The package uses testthat for unit testing framework +- Interactive plots use Plotly.js via JavaScript templates in `inst/js/` +- The y-axis ordering in `format_ae_forestly.R` affects the visual display in interactive plots +- When debugging interactive plot issues, check both R code and JavaScript template files \ No newline at end of file diff --git a/R/format_ae_forestly.R b/R/format_ae_forestly.R index 5f5fcca..3046ab9 100644 --- a/R/format_ae_forestly.R +++ b/R/format_ae_forestly.R @@ -77,6 +77,8 @@ format_ae_forestly <- function( several.ok = TRUE ) + display_n <- "n" %in% display + display_prop <- "prop" %in% display display_total <- "total" %in% display display_diff <- "diff" %in% display @@ -131,7 +133,7 @@ format_ae_forestly <- function( tbl_prop <- outdata$prop[, 1:n_group] y <- rep(NA, n_group) y[outdata$reference_group] <- mean(1:n_group1) - y[-outdata$reference_group] <- 1:n_group1 + y[-outdata$reference_group] <- rev(1:n_group1) # Calculate the range of the forest plot if (is.null(prop_range)) { @@ -199,7 +201,7 @@ format_ae_forestly <- function( x = names(outdata$diff), x_lower = names(outdata$ci_lower), x_upper = names(outdata$ci_upper), - y = 1:ncol(outdata$diff), + y = rev(1:ncol(outdata$diff)), xlim = fig_diff_range, color = fig_diff_color, width = width_fig, @@ -259,7 +261,8 @@ format_ae_forestly <- function( col_n <- lapply(name_n, function(x) { reactable::colDef( header = "n", defaultSortOrder = "desc", - minWidth = width_n, align = "center" + minWidth = width_n, align = "center", + show = display_n ) }) names(col_n) <- name_n @@ -269,6 +272,7 @@ format_ae_forestly <- function( reactable::colDef( header = "(%)", defaultSortOrder = "desc", minWidth = width_prop, align = "center", + show = display_prop, format = reactable::colFormat( prefix = "(", digits = digits,