Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
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
14 changes: 14 additions & 0 deletions ..Rcheck/00check.log
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we get rid of this log file and its ..Rcheck folder?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in #54

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
* using log directory ‘/Users/Anderkea/Documents/GitHub/wpgsd/..Rcheck’
* using R version 4.5.0 (2025-04-11)
* using platform: aarch64-apple-darwin20
* R was compiled by
Apple clang version 14.0.0 (clang-1400.0.29.202)
GNU Fortran (GCC) 14.2.0
* running under: macOS Sequoia 15.6.1
* using session charset: UTF-8
* using option ‘--no-manual’
* checking for file ‘./DESCRIPTION’ ... ERROR
Required fields missing or empty:
‘Author’ ‘Maintainer’
* DONE
Status: 1 ERROR
2 changes: 2 additions & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@
^\.github$
^codecov\.yml$
^CITATION\.cff$
^doc$
^Meta$
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
.Ruserdata
.DS_Store
docs
/doc/
/Meta/
5 changes: 3 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: wpgsd
Title: Weighted Parametric Group Sequential Design
Version: 0.1.0
Version: 0.3.0
Authors@R: c(
person("Keaven", "Anderson", email = "keaven_anderson@merck.com", role = "aut"),
person("Zifang", "Guo", email = "zifang.guo@merck.com", role = "aut"),
Expand Down Expand Up @@ -31,6 +31,7 @@ Imports:
gsDesign,
mvtnorm,
rlang (>= 0.4.11),
S7,
stats,
tibble,
tidyselect
Expand All @@ -48,4 +49,4 @@ VignetteBuilder:
knitr
Config/testthat/edition: 3
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.1
RoxygenNote: 7.3.3
128 changes: 128 additions & 0 deletions EventTable_README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# EventTable S7 Class Implementation

## Overview

The `EventTable` S7 class provides a type-safe, validated data structure for representing event count data used in the wpgsd package. This is the first step in converting the wpgsd package to use S7 classes throughout.

## Features

### Core Properties
- **data**: A tibble containing the event count data with required columns `H1`, `H2`, `Analysis`, `Event`
- **n_hypotheses**: Automatically calculated number of hypotheses
- **n_analyses**: Automatically calculated number of analyses

### Validation
- Validates presence of required columns (`H1`, `H2`, `Analysis`, `Event`)
- Ensures proper data types (all numeric)
- Validates logical constraints:
- Hypothesis indices must be positive integers
- Analysis numbers must be positive integers
- Event counts must be non-negative
- Enforces mathematical consistency requirements:
- For a fixed H1, H2 pair, Event counts must be non-decreasing as Analysis increases
- For off-diagonal entries (H1 ≠ H2), diagonal entries must exist with Event ≥ off-diagonal Event for the same Analysis
- These constraints ensure proper mathematical properties for correlation matrix calculations

### Methods
- **print()**: Clean formatted output showing key information
- **summary()**: Detailed summary including event count statistics
- **subset_event_table()**: Subset by analysis or hypotheses
- **as_event_table()**: Convert tibble to EventTable
- **validate_event_table_data()**: Validate data format before processing

## Usage Examples

### Basic Usage
```r
library(wpgsd)

# Create event data
event_data <- tibble::tribble(
~H1, ~H2, ~Analysis, ~Event,
1, 1, 1, 155,
2, 2, 1, 160,
1, 2, 1, 85,
1, 1, 2, 305,
2, 2, 2, 320,
1, 2, 2, 170
)

# Create EventTable object
event_table <- EventTable(data = event_data)
print(event_table)
```

### Data Validation
```r
# The constructor automatically validates data
tryCatch({
invalid_data <- tibble::tibble(
H1 = c(1, -2), # Invalid: negative hypothesis index
H2 = c(1, 2),
Analysis = c(1, 1),
Event = c(100, 200)
)
EventTable(data = invalid_data)
}, error = function(e) {
cat("Validation error:", e$message)
})
```

### Subsetting
```r
# Subset by analysis
analysis_1 <- subset_event_table(event_table, analysis = 1)

# Subset by hypotheses
h1_h2 <- subset_event_table(event_table, hypotheses = c(1, 2))
```

### Integration with Existing Functions
```r
# Use with existing wpgsd functions
correlation_matrix <- generate_corr(event_table@data)
```

## Files Created

- `R/s7_classes.R`: Main S7 class definition
- `tests/testthat/test-s7-event-table.R`: Comprehensive unit tests
- `examples/test_event_table.R`: Basic usage examples
- `examples/event_table_integration.R`: Integration with existing functions

## Dependencies

- Added `S7` to package imports in `DESCRIPTION`
- Uses existing dependencies: `tibble`, `dplyr`

## Benefits

1. **Type Safety**: Prevents invalid data from being passed to wpgsd functions
2. **Validation**: Automatic validation of data format and constraints
3. **Documentation**: Self-documenting data structures
4. **Method Dispatch**: Extensible with specialized methods
5. **User Experience**: Clear error messages and helpful summaries

## Next Steps

This EventTable implementation provides the foundation for converting the wpgsd package to S7 classes. Future steps include:

1. Create `CorrelationMatrix` S7 class for `generate_corr()` output
2. Create `Bounds` S7 class for `generate_bounds()` output
3. Update existing functions to accept/return S7 objects
4. Maintain backward compatibility with existing tibble/data.frame inputs

## Testing

Run the comprehensive test suite:
```r
testthat::test_file("tests/testthat/test-s7-event-table.R")
```

The tests cover:
- Object creation with valid data
- Validation of required columns
- Data type and value validation
- Print and summary methods
- Subsetting functionality
- Data conversion utilities
23 changes: 23 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,40 @@

export(":=")
export(.data)
export(CorrelationMatrix)
export(EventTable)
export(as_correlation_matrix)
export(as_event_table)
export(as_label)
export(as_name)
export(calc_seq_p)
export(check_event_data)
export(closed_test)
export(compute_correlations)
export(enquo)
export(enquos)
export(find_astar)
export(find_xi)
export(gen_corr)
export(generate_bounds)
export(generate_corr)
export(generate_corr_s7)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this PR did not replace the existing generate_corr() with an S7 version (#46). Instead, it created an additional function generate_corr_s7().

export(generate_event_table)
export(generate_event_table_)
export(generate_event_table_cc)
export(generate_event_table_ol)
export(subset_correlation_matrix)
export(subset_event_table)
export(validate_event_table_data)
importFrom(S7,S7_inherits)
importFrom(S7,S7_object)
importFrom(S7,class_character)
importFrom(S7,class_data.frame)
importFrom(S7,class_integer)
importFrom(S7,method)
importFrom(S7,new_S3_class)
importFrom(S7,new_class)
importFrom(S7,new_object)
importFrom(dplyr,"%>%")
importFrom(dplyr,arrange)
importFrom(dplyr,bind_rows)
Expand Down
72 changes: 72 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,75 @@
# wpgsd 0.3.0

## New Features

- **Dunnett-type dose-finding vignette**: Added new vignette demonstrating Dunnett-type group sequential design with 2 experimental arms vs. common control and 3 analyses (2 interims + final), exercising correlation computation for K > 2.

## Improvements

- Completed S7 wrapper function elimination and validation refactoring.
- Organized help files into logical sections for better usability.
- Removed empty `adj-seq-p-simplified.Rmd` vignette that caused UNKNOWN TITLE in pkgdown navigation.

## Bug Fixes

- Fixed `generate_corr()` correlation computation for K > 2 analyses: within-hypothesis and between-hypotheses loops now correctly enumerate all analysis pairs.
- Fixed S7 `EventTable` validator to allow single-analysis and single-hypothesis event tables (e.g., after subsetting).
- Fixed `validate_event_data_core()` crash when non-numeric data is passed to `floor()` checks.
- Fixed inconsistent error message formatting in diagonal entry validation (`paste` → `paste0`).
- Corrected test expectations to match actual validation error messages.

# wpgsd 0.2.0

## Major Features

- **S7 Class System Integration**: Complete implementation of S7 classes for enhanced type safety and validation
- `EventTable` class with robust validation for event data structures
- `CorrelationMatrix` class with symmetry and positive definiteness validation
- Improved `generate_corr()` function with S7 class support

## Code Quality Improvements

### Validation System Refactoring
- **Eliminated ~80% code duplication** between `check_event_data()`, `validate_event_table_data()`, and `EventTable` validator method through centralized `validate_event_data_core()` function
- **Improved validation consistency** with three validation levels: "basic", "strict", and "s7" to support different use cases
- **Enhanced error handling** with clearer, more specific error messages for validation failures
- **Relaxed Event value requirements** to allow non-integer values (e.g., 100.5 events) while maintaining H1, H2, and Analysis as positive integers

### S7 Class Implementation Improvements
- **Removed redundant wrapper functions** `new_event_table()` and `new_correlation_matrix()` following S7 best practices
- **Enhanced S7 class documentation** with comprehensive parameter descriptions, validation details, and usage examples
- **Improved API consistency** by using direct S7 class constructors (`EventTable()`, `CorrelationMatrix()`) throughout codebase
- **Updated all examples and tests** to use proper S7 constructor patterns instead of wrapper functions

### Testing and Documentation Updates
- **Updated test suite** to reflect validation changes and S7 constructor usage
- **Regenerated package documentation** with roxygen2 to remove deprecated wrapper function documentation
- **Enhanced code maintainability** through consolidated validation logic and cleaner S7 implementation

## Bug Fixes and Improvements

- Fixed correlation matrix validation tolerance issues (improved numerical precision handling with 1e-12 tolerance)
- Resolved non-ASCII character issues in documentation for better portability
- Added missing `@export` tags for proper function exports
- Enhanced roxygen2 documentation with clearer parameter descriptions

## Documentation and Vignettes

- **Significantly improved `adj-seq-p` vignette**:
- Reduced code repetition by ~80% through systematic helper functions
- Enhanced readability while maintaining technical accuracy
- Added comprehensive multiplicity strategy visualization
- Improved mathematical notation and explanations
- Added proper citations (@zhao2025adjusted)
- Updated correlation calculation vignette with S7 class examples

## Package Infrastructure

- Enhanced unit tests with 132+ passing test cases
- Improved package build process with better error handling
- Updated NAMESPACE with proper exports
- Enhanced pkgdown documentation site generation

# wpgsd 0.1.0

- Initial release.
Expand Down
61 changes: 31 additions & 30 deletions R/calc_seq_p.R
Original file line number Diff line number Diff line change
Expand Up @@ -80,37 +80,38 @@
#' )
#' }
calc_seq_p <- function(
test_analysis = 2,
test_hypothesis = "H1, H2, H3",
p_obs = tibble::tibble(
analysis = 1:2,
H1 = c(0.02, 0.0015),
H2 = c(0.01, 0.01),
H3 = c(0.01, 0.004)
test_analysis = 2,
test_hypothesis = "H1, H2, H3",
p_obs = tibble::tibble(
analysis = 1:2,
H1 = c(0.02, 0.0015),
H2 = c(0.01, 0.01),
H3 = c(0.01, 0.004)
),
alpha_spending_type = 2,
n_analysis = 2,
initial_weight = c(0.3, 0.3, 0.4),
transition_mat = matrix(c(
0.0000000, 0.4285714, 0.5714286,
0.4285714, 0.0000000, 0.5714286,
0.5000000, 0.5000000, 0.0000000
), nrow = 3, byrow = TRUE),
z_corr = matrix(
c(
1.0000000, 0.7627701, 0.6666667, 0.7071068, 0.5393599, 0.4714045,
0.7627701, 1.0000000, 0.6992059, 0.5393599, 0.7071068, 0.4944132,
0.6666667, 0.6992059, 1.0000000, 0.4714045, 0.4944132, 0.7071068,
0.7071068, 0.5393599, 0.4714045, 1.0000000, 0.7627701, 0.6666667,
0.5393599, 0.7071068, 0.4944132, 0.7627701, 1.0000000, 0.6992059,
0.4714045, 0.4944132, 0.7071068, 0.6666667, 0.6992059, 1.0000000
),
alpha_spending_type = 2,
n_analysis = 2,
initial_weight = c(0.3, 0.3, 0.4),
transition_mat = matrix(c(
0.0000000, 0.4285714, 0.5714286,
0.4285714, 0.0000000, 0.5714286,
0.5000000, 0.5000000, 0.0000000
), nrow = 3, byrow = TRUE),
z_corr = matrix(
c(
1.0000000, 0.7627701, 0.6666667, 0.7071068, 0.5393599, 0.4714045,
0.7627701, 1.0000000, 0.6992059, 0.5393599, 0.7071068, 0.4944132,
0.6666667, 0.6992059, 1.0000000, 0.4714045, 0.4944132, 0.7071068,
0.7071068, 0.5393599, 0.4714045, 1.0000000, 0.7627701, 0.6666667,
0.5393599, 0.7071068, 0.4944132, 0.7627701, 1.0000000, 0.6992059,
0.4714045, 0.4944132, 0.7071068, 0.6666667, 0.6992059, 1.0000000
),
nrow = 6, byrow = TRUE
),
spending_fun = gsDesign::sfHSD,
spending_fun_par = -4,
info_frac = c(0.5, 1),
interval = c(1e-4, 0.2)) {
nrow = 6, byrow = TRUE
),
spending_fun = gsDesign::sfHSD,
spending_fun_par = -4,
info_frac = c(0.5, 1),
interval = c(1e-4, 0.2)
) {
foo <- function(x) {
all_hypothesis <- strsplit(test_hypothesis, split = ", ") %>% unlist()
all_hypothesis_idx <- as.numeric(gsub(".*?([0-9]+).*", "\\1", all_hypothesis))
Expand Down
Loading
Loading