Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
^pkgdown$
^Makefile$
^CRAN-SUBMISSION$
^CLAUDE\.md$
121 changes: 121 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.


## Standard Workflow

1. **First think through the problem, read the codebase for relevant files, and write a plan to tasks/todo.md.**

2. **The plan should have a list of todo items that you can check off as you complete them**

3. **Before you begin working, check in with me and I will verify the plan.**

4. **Then, begin working on the todo items, marking them as complete as you go.**

5. **Please every step of the way just give me a high level explanation of what changes you made**

6. **Make every task and code change you do as simple as possible. We want to avoid making any massive or complex changes. Every change should impact as little code as possible. Everything is about simplicity.**

7. **Finally, add a review section to the todo.md file with a summary of the changes you made and any other relevant information.**


## Overview

survminer is an R package for survival analysis and visualization built on ggplot2. It provides functions for drawing publication-ready survival curves with risk tables and diagnostic plots for Cox proportional hazards models.

## Development Commands


### Load and test during the development

```bash
Rscript -e "devtools::load_all()"
Rscript -e "devtools::document()"
Rscript -e "devtools::test()"
```


### Package Checking

```bash
Rscript -e "devtools::check()"
Rscript -e "urlchecker::url_check()"
```

### Install

```bash
Rscript -e "devtools::install()"
```


## Commit and pull request text strategy

- neither add the following in commit message or pull request text:

```
Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>"
```
- don't use emojis like 📝, 📢, etc



## Package Architecture

### Core Components

The package is organized into several functional areas:

**Main Plotting Functions** (`R/ggsurvplot*.R`):
- `ggsurvplot_core.R`: Core survival curve plotting engine
- `ggsurvplot.R`: Main user-facing function with multiple dispatch
- `ggsurvplot_df.R`: Plot from data frame summaries
- `ggsurvplot_list.R`: Handle lists of survfit objects
- `ggsurvplot_facet.R`: Multi-panel faceted plots
- `ggsurvplot_group_by.R`: Group-wise plotting
- `ggsurvplot_combine.R`: Combine multiple survival curves

**Cox Model Diagnostics** (`R/ggcox*.R`):
- `ggcoxdiagnostics.R`: Model fit diagnostics
- `ggcoxfunctional.R`: Functional form assessment
- `ggcoxzph.R`: Proportional hazards testing
- `ggforest.R`: Forest plots for hazard ratios

**Utility Functions**:
- `utilities.R`: Core helper functions and imports
- `surv_summary.R`: Create tidy survival summaries
- `surv_pvalue.R`: Calculate log-rank test p-values
- `ggsurvtable.R`: Risk tables and event tables

### Dependencies

Built on tidyverse ecosystem with key dependencies:
- `ggplot2` (≥3.4.0): Core plotting
- `ggpubr` (≥0.1.6): Publication-ready themes
- `survival`: Survival analysis functions
- `dplyr`, `tidyr`, `purrr`: Data manipulation
- `ggtext`: Enhanced text formatting

### Testing Structure

Tests use `testthat` framework located in `tests/testthat/`:
- Test files follow `test-[function].R` naming convention
- `setup-load_data.R`: Common test data setup
- Main test entry point: `tests/testthat.R`

### Documentation

- Function documentation: `man/*.Rd` (auto-generated by roxygen2)
- Vignettes: `vignettes/*.Rmd` with detailed examples
- Package website: Built with pkgdown using `_pkgdown.yml` configuration
- Cheatsheet: `pkgdown/cheatsheet/survminer_cheatsheet.pdf`

## Key Design Patterns

1. **Function Hierarchy**: `ggsurvplot()` acts as dispatcher to specialized `ggsurvplot_*()` functions
2. **S3 Methods**: Uses S3 dispatch for print methods and plotting
3. **ggplot2 Integration**: Returns ggplot objects that can be further customized
4. **Modular Components**: Survival plots, risk tables, and censor plots are separate components that can be combined
5. **Data Pipeline**: `survfit` → `surv_summary()` → `ggsurvplot_df()` for custom workflows
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

## Bug fixes

- Fix compatibility with ggplot2 development version (#681): Remove manual class assignment in `theme_survminer()` to ensure proper theme object construction
- Fix test suite compatibility with ggplot2 development version (#681): Update layer access syntax in tests to support both stable (`$layers`) and development (`@layers`) versions



# Survminer 0.5.0
Expand Down
1 change: 0 additions & 1 deletion R/ggsurvtheme.R
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ theme_survminer <-
legend.text = legend.text,
legend.title = legend.text
)
class(result) <- "theme"
result
}

Expand Down
8 changes: 8 additions & 0 deletions R/utilities.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@
#' @importFrom rlang !! sym


# Check if an installed package version is superior to a specified version
# Version, pkg: character vector
is_pkg_version_sup<- function(pkg, version){
vv <- as.character(utils::packageVersion(pkg))
cc <- utils::compareVersion(vv, version) > 0
cc
}

# Count the number of ggplots in a list
.count_ggplots <- function(list.objects){
nplot <- 0
Expand Down
10 changes: 8 additions & 2 deletions tests/testthat/test-ggsurvplot_facet.R
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ test_that("ggsurvplot_facet calculates pvalue for each facet", {
fit <- survfit(Surv(time, status) ~ sex, data=kidney)
p <- ggsurvplot_facet(fit, kidney, facet.by='disease', pval = TRUE)
.build <- ggplot_build(p)
expect_equal(nrow(.build$plot$layer[[4]][['data']]),
length(unique(kidney[['disease']])))

# Handle ggplot2 dev version layer access syntax change
if (is_pkg_version_sup("ggplot2", "3.5.2")) {
observed <- nrow(.build$plot@layers[[4]][['data']])
} else {
observed <- nrow(.build$plot$layers[[4]][['data']])
}
expect_equal(observed, length(unique(kidney[['disease']])))
})
Loading