Skip to content

Commit 2ee3089

Browse files
authored
Merge pull request #52 from Merck/46-s7-change-generate_corr-to-s7
Add Dunnett-type 4-dose GSD vignette and bump version to 0.3.0
2 parents 8839951 + 1620b6f commit 2ee3089

249 files changed

Lines changed: 102212 additions & 909 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

..Rcheck/00check.log

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
* using log directory ‘/Users/Anderkea/Documents/GitHub/wpgsd/..Rcheck’
2+
* using R version 4.5.0 (2025-04-11)
3+
* using platform: aarch64-apple-darwin20
4+
* R was compiled by
5+
Apple clang version 14.0.0 (clang-1400.0.29.202)
6+
GNU Fortran (GCC) 14.2.0
7+
* running under: macOS Sequoia 15.6.1
8+
* using session charset: UTF-8
9+
* using option ‘--no-manual’
10+
* checking for file ‘./DESCRIPTION’ ... ERROR
11+
Required fields missing or empty:
12+
‘Author’ ‘Maintainer’
13+
* DONE
14+
Status: 1 ERROR

.Rbuildignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@
88
^\.github$
99
^codecov\.yml$
1010
^CITATION\.cff$
11+
^doc$
12+
^Meta$

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@
44
.Ruserdata
55
.DS_Store
66
docs
7+
/doc/
8+
/Meta/

DESCRIPTION

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: wpgsd
22
Title: Weighted Parametric Group Sequential Design
3-
Version: 0.1.0
3+
Version: 0.3.0
44
Authors@R: c(
55
person("Keaven", "Anderson", email = "keaven_anderson@merck.com", role = "aut"),
66
person("Zifang", "Guo", email = "zifang.guo@merck.com", role = "aut"),
@@ -31,6 +31,7 @@ Imports:
3131
gsDesign,
3232
mvtnorm,
3333
rlang (>= 0.4.11),
34+
S7,
3435
stats,
3536
tibble,
3637
tidyselect
@@ -48,4 +49,4 @@ VignetteBuilder:
4849
knitr
4950
Config/testthat/edition: 3
5051
Roxygen: list(markdown = TRUE)
51-
RoxygenNote: 7.3.1
52+
RoxygenNote: 7.3.3

EventTable_README.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# EventTable S7 Class Implementation
2+
3+
## Overview
4+
5+
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.
6+
7+
## Features
8+
9+
### Core Properties
10+
- **data**: A tibble containing the event count data with required columns `H1`, `H2`, `Analysis`, `Event`
11+
- **n_hypotheses**: Automatically calculated number of hypotheses
12+
- **n_analyses**: Automatically calculated number of analyses
13+
14+
### Validation
15+
- Validates presence of required columns (`H1`, `H2`, `Analysis`, `Event`)
16+
- Ensures proper data types (all numeric)
17+
- Validates logical constraints:
18+
- Hypothesis indices must be positive integers
19+
- Analysis numbers must be positive integers
20+
- Event counts must be non-negative
21+
- Enforces mathematical consistency requirements:
22+
- For a fixed H1, H2 pair, Event counts must be non-decreasing as Analysis increases
23+
- For off-diagonal entries (H1 ≠ H2), diagonal entries must exist with Event ≥ off-diagonal Event for the same Analysis
24+
- These constraints ensure proper mathematical properties for correlation matrix calculations
25+
26+
### Methods
27+
- **print()**: Clean formatted output showing key information
28+
- **summary()**: Detailed summary including event count statistics
29+
- **subset_event_table()**: Subset by analysis or hypotheses
30+
- **as_event_table()**: Convert tibble to EventTable
31+
- **validate_event_table_data()**: Validate data format before processing
32+
33+
## Usage Examples
34+
35+
### Basic Usage
36+
```r
37+
library(wpgsd)
38+
39+
# Create event data
40+
event_data <- tibble::tribble(
41+
~H1, ~H2, ~Analysis, ~Event,
42+
1, 1, 1, 155,
43+
2, 2, 1, 160,
44+
1, 2, 1, 85,
45+
1, 1, 2, 305,
46+
2, 2, 2, 320,
47+
1, 2, 2, 170
48+
)
49+
50+
# Create EventTable object
51+
event_table <- EventTable(data = event_data)
52+
print(event_table)
53+
```
54+
55+
### Data Validation
56+
```r
57+
# The constructor automatically validates data
58+
tryCatch({
59+
invalid_data <- tibble::tibble(
60+
H1 = c(1, -2), # Invalid: negative hypothesis index
61+
H2 = c(1, 2),
62+
Analysis = c(1, 1),
63+
Event = c(100, 200)
64+
)
65+
EventTable(data = invalid_data)
66+
}, error = function(e) {
67+
cat("Validation error:", e$message)
68+
})
69+
```
70+
71+
### Subsetting
72+
```r
73+
# Subset by analysis
74+
analysis_1 <- subset_event_table(event_table, analysis = 1)
75+
76+
# Subset by hypotheses
77+
h1_h2 <- subset_event_table(event_table, hypotheses = c(1, 2))
78+
```
79+
80+
### Integration with Existing Functions
81+
```r
82+
# Use with existing wpgsd functions
83+
correlation_matrix <- generate_corr(event_table@data)
84+
```
85+
86+
## Files Created
87+
88+
- `R/s7_classes.R`: Main S7 class definition
89+
- `tests/testthat/test-s7-event-table.R`: Comprehensive unit tests
90+
- `examples/test_event_table.R`: Basic usage examples
91+
- `examples/event_table_integration.R`: Integration with existing functions
92+
93+
## Dependencies
94+
95+
- Added `S7` to package imports in `DESCRIPTION`
96+
- Uses existing dependencies: `tibble`, `dplyr`
97+
98+
## Benefits
99+
100+
1. **Type Safety**: Prevents invalid data from being passed to wpgsd functions
101+
2. **Validation**: Automatic validation of data format and constraints
102+
3. **Documentation**: Self-documenting data structures
103+
4. **Method Dispatch**: Extensible with specialized methods
104+
5. **User Experience**: Clear error messages and helpful summaries
105+
106+
## Next Steps
107+
108+
This EventTable implementation provides the foundation for converting the wpgsd package to S7 classes. Future steps include:
109+
110+
1. Create `CorrelationMatrix` S7 class for `generate_corr()` output
111+
2. Create `Bounds` S7 class for `generate_bounds()` output
112+
3. Update existing functions to accept/return S7 objects
113+
4. Maintain backward compatibility with existing tibble/data.frame inputs
114+
115+
## Testing
116+
117+
Run the comprehensive test suite:
118+
```r
119+
testthat::test_file("tests/testthat/test-s7-event-table.R")
120+
```
121+
122+
The tests cover:
123+
- Object creation with valid data
124+
- Validation of required columns
125+
- Data type and value validation
126+
- Print and summary methods
127+
- Subsetting functionality
128+
- Data conversion utilities

NAMESPACE

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,40 @@
22

33
export(":=")
44
export(.data)
5+
export(CorrelationMatrix)
6+
export(EventTable)
7+
export(as_correlation_matrix)
8+
export(as_event_table)
59
export(as_label)
610
export(as_name)
711
export(calc_seq_p)
12+
export(check_event_data)
813
export(closed_test)
14+
export(compute_correlations)
915
export(enquo)
1016
export(enquos)
1117
export(find_astar)
1218
export(find_xi)
19+
export(gen_corr)
1320
export(generate_bounds)
1421
export(generate_corr)
22+
export(generate_corr_s7)
1523
export(generate_event_table)
24+
export(generate_event_table_)
25+
export(generate_event_table_cc)
26+
export(generate_event_table_ol)
27+
export(subset_correlation_matrix)
28+
export(subset_event_table)
29+
export(validate_event_table_data)
30+
importFrom(S7,S7_inherits)
31+
importFrom(S7,S7_object)
32+
importFrom(S7,class_character)
33+
importFrom(S7,class_data.frame)
34+
importFrom(S7,class_integer)
35+
importFrom(S7,method)
36+
importFrom(S7,new_S3_class)
37+
importFrom(S7,new_class)
38+
importFrom(S7,new_object)
1639
importFrom(dplyr,"%>%")
1740
importFrom(dplyr,arrange)
1841
importFrom(dplyr,bind_rows)

NEWS.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,75 @@
1+
# wpgsd 0.3.0
2+
3+
## New Features
4+
5+
- **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.
6+
7+
## Improvements
8+
9+
- Completed S7 wrapper function elimination and validation refactoring.
10+
- Organized help files into logical sections for better usability.
11+
- Removed empty `adj-seq-p-simplified.Rmd` vignette that caused UNKNOWN TITLE in pkgdown navigation.
12+
13+
## Bug Fixes
14+
15+
- Fixed `generate_corr()` correlation computation for K > 2 analyses: within-hypothesis and between-hypotheses loops now correctly enumerate all analysis pairs.
16+
- Fixed S7 `EventTable` validator to allow single-analysis and single-hypothesis event tables (e.g., after subsetting).
17+
- Fixed `validate_event_data_core()` crash when non-numeric data is passed to `floor()` checks.
18+
- Fixed inconsistent error message formatting in diagonal entry validation (`paste``paste0`).
19+
- Corrected test expectations to match actual validation error messages.
20+
21+
# wpgsd 0.2.0
22+
23+
## Major Features
24+
25+
- **S7 Class System Integration**: Complete implementation of S7 classes for enhanced type safety and validation
26+
- `EventTable` class with robust validation for event data structures
27+
- `CorrelationMatrix` class with symmetry and positive definiteness validation
28+
- Improved `generate_corr()` function with S7 class support
29+
30+
## Code Quality Improvements
31+
32+
### Validation System Refactoring
33+
- **Eliminated ~80% code duplication** between `check_event_data()`, `validate_event_table_data()`, and `EventTable` validator method through centralized `validate_event_data_core()` function
34+
- **Improved validation consistency** with three validation levels: "basic", "strict", and "s7" to support different use cases
35+
- **Enhanced error handling** with clearer, more specific error messages for validation failures
36+
- **Relaxed Event value requirements** to allow non-integer values (e.g., 100.5 events) while maintaining H1, H2, and Analysis as positive integers
37+
38+
### S7 Class Implementation Improvements
39+
- **Removed redundant wrapper functions** `new_event_table()` and `new_correlation_matrix()` following S7 best practices
40+
- **Enhanced S7 class documentation** with comprehensive parameter descriptions, validation details, and usage examples
41+
- **Improved API consistency** by using direct S7 class constructors (`EventTable()`, `CorrelationMatrix()`) throughout codebase
42+
- **Updated all examples and tests** to use proper S7 constructor patterns instead of wrapper functions
43+
44+
### Testing and Documentation Updates
45+
- **Updated test suite** to reflect validation changes and S7 constructor usage
46+
- **Regenerated package documentation** with roxygen2 to remove deprecated wrapper function documentation
47+
- **Enhanced code maintainability** through consolidated validation logic and cleaner S7 implementation
48+
49+
## Bug Fixes and Improvements
50+
51+
- Fixed correlation matrix validation tolerance issues (improved numerical precision handling with 1e-12 tolerance)
52+
- Resolved non-ASCII character issues in documentation for better portability
53+
- Added missing `@export` tags for proper function exports
54+
- Enhanced roxygen2 documentation with clearer parameter descriptions
55+
56+
## Documentation and Vignettes
57+
58+
- **Significantly improved `adj-seq-p` vignette**:
59+
- Reduced code repetition by ~80% through systematic helper functions
60+
- Enhanced readability while maintaining technical accuracy
61+
- Added comprehensive multiplicity strategy visualization
62+
- Improved mathematical notation and explanations
63+
- Added proper citations (@zhao2025adjusted)
64+
- Updated correlation calculation vignette with S7 class examples
65+
66+
## Package Infrastructure
67+
68+
- Enhanced unit tests with 132+ passing test cases
69+
- Improved package build process with better error handling
70+
- Updated NAMESPACE with proper exports
71+
- Enhanced pkgdown documentation site generation
72+
173
# wpgsd 0.1.0
274

375
- Initial release.

R/calc_seq_p.R

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -80,37 +80,38 @@
8080
#' )
8181
#' }
8282
calc_seq_p <- function(
83-
test_analysis = 2,
84-
test_hypothesis = "H1, H2, H3",
85-
p_obs = tibble::tibble(
86-
analysis = 1:2,
87-
H1 = c(0.02, 0.0015),
88-
H2 = c(0.01, 0.01),
89-
H3 = c(0.01, 0.004)
83+
test_analysis = 2,
84+
test_hypothesis = "H1, H2, H3",
85+
p_obs = tibble::tibble(
86+
analysis = 1:2,
87+
H1 = c(0.02, 0.0015),
88+
H2 = c(0.01, 0.01),
89+
H3 = c(0.01, 0.004)
90+
),
91+
alpha_spending_type = 2,
92+
n_analysis = 2,
93+
initial_weight = c(0.3, 0.3, 0.4),
94+
transition_mat = matrix(c(
95+
0.0000000, 0.4285714, 0.5714286,
96+
0.4285714, 0.0000000, 0.5714286,
97+
0.5000000, 0.5000000, 0.0000000
98+
), nrow = 3, byrow = TRUE),
99+
z_corr = matrix(
100+
c(
101+
1.0000000, 0.7627701, 0.6666667, 0.7071068, 0.5393599, 0.4714045,
102+
0.7627701, 1.0000000, 0.6992059, 0.5393599, 0.7071068, 0.4944132,
103+
0.6666667, 0.6992059, 1.0000000, 0.4714045, 0.4944132, 0.7071068,
104+
0.7071068, 0.5393599, 0.4714045, 1.0000000, 0.7627701, 0.6666667,
105+
0.5393599, 0.7071068, 0.4944132, 0.7627701, 1.0000000, 0.6992059,
106+
0.4714045, 0.4944132, 0.7071068, 0.6666667, 0.6992059, 1.0000000
90107
),
91-
alpha_spending_type = 2,
92-
n_analysis = 2,
93-
initial_weight = c(0.3, 0.3, 0.4),
94-
transition_mat = matrix(c(
95-
0.0000000, 0.4285714, 0.5714286,
96-
0.4285714, 0.0000000, 0.5714286,
97-
0.5000000, 0.5000000, 0.0000000
98-
), nrow = 3, byrow = TRUE),
99-
z_corr = matrix(
100-
c(
101-
1.0000000, 0.7627701, 0.6666667, 0.7071068, 0.5393599, 0.4714045,
102-
0.7627701, 1.0000000, 0.6992059, 0.5393599, 0.7071068, 0.4944132,
103-
0.6666667, 0.6992059, 1.0000000, 0.4714045, 0.4944132, 0.7071068,
104-
0.7071068, 0.5393599, 0.4714045, 1.0000000, 0.7627701, 0.6666667,
105-
0.5393599, 0.7071068, 0.4944132, 0.7627701, 1.0000000, 0.6992059,
106-
0.4714045, 0.4944132, 0.7071068, 0.6666667, 0.6992059, 1.0000000
107-
),
108-
nrow = 6, byrow = TRUE
109-
),
110-
spending_fun = gsDesign::sfHSD,
111-
spending_fun_par = -4,
112-
info_frac = c(0.5, 1),
113-
interval = c(1e-4, 0.2)) {
108+
nrow = 6, byrow = TRUE
109+
),
110+
spending_fun = gsDesign::sfHSD,
111+
spending_fun_par = -4,
112+
info_frac = c(0.5, 1),
113+
interval = c(1e-4, 0.2)
114+
) {
114115
foo <- function(x) {
115116
all_hypothesis <- strsplit(test_hypothesis, split = ", ") %>% unlist()
116117
all_hypothesis_idx <- as.numeric(gsub(".*?([0-9]+).*", "\\1", all_hypothesis))

0 commit comments

Comments
 (0)