library(Saqrlab)
#>
#> Attaching package: 'Saqrlab'
#> The following object is masked from 'package:stats':
#>
#> simulateThis vignette covers bootstrap analysis and power analysis for TNA studies using Saqrlab. You’ll learn how to:
Bootstrap helps answer: - How stable are my network estimates? - What’s the confidence interval for edge weights? - Are my centrality rankings reliable?
Power analysis helps answer: - How many sequences do I need for reliable results? - What sequence length is sufficient? - How do sample size and network size interact?
library(tna)
# Generate some data
sequences <- simulate_sequences(
n_sequences = 150,
seq_length = 25,
n_states = 5,
seed = 42
)
# Fit original model
original_model <- fit_network_model(sequences, "tna")
# Run bootstrap
bootstrap_results <- run_bootstrap_simulation(
original_data = sequences,
n_bootstrap = 100,
model_type = "tna",
sample_size = NULL, # Use original size
parallel = TRUE,
seed = 42
)# Define stable transitions to test
stable_transitions <- list(
c("Plan", "Monitor"),
c("Monitor", "Evaluate")
)
# Bootstrap with stability testing
bootstrap_results <- run_bootstrap_simulation(
original_data = sequences,
n_bootstrap = 100,
model_type = "tna",
stable_transitions = stable_transitions,
seed = 42
)The most comprehensive approach uses parameter grids:
# Find minimum n_sequences for target correlation
target_correlation <- 0.90
summary_by_n <- summarize_simulation(
results = power_results,
by = "n_sequences",
metrics = c("mean", "ci_lower")
)
# Find first sample size meeting target
min_n <- summary_by_n$n_sequences[
which(summary_by_n$correlation_mean >= target_correlation)[1]
]
cat("Minimum sample size for r >=", target_correlation, ":", min_n)For specific scenarios, run targeted simulations:
# Define ground truth
true_probs <- generate_probabilities(n_states = 5, seed = 42)
# Test specific sample sizes
sample_sizes <- c(25, 50, 75, 100, 125, 150, 200, 300, 500)
power_results <- lapply(sample_sizes, function(n) {
# Run multiple replications
correlations <- sapply(1:100, function(rep) {
# Generate sequences
seqs <- simulate_sequences(
trans_matrix = true_probs$transition_matrix,
init_probs = true_probs$initial_probs,
n_sequences = n,
seq_length = 25,
seed = rep * 1000 + n
)
# Fit model
model <- fit_network_model(seqs, "tna")
# Compare to truth
estimated <- extract_transition_matrix(model, type = "scaled")
cor(as.vector(true_probs$transition_matrix),
as.vector(estimated))
})
data.frame(
n_sequences = n,
mean_r = mean(correlations),
sd_r = sd(correlations),
ci_lower = mean(correlations) - 1.96 * sd(correlations),
ci_upper = mean(correlations) + 1.96 * sd(correlations),
prop_above_90 = mean(correlations >= 0.90)
)
})
power_df <- do.call(rbind, power_results)
print(power_df)| Metric | Description | Target |
|---|---|---|
| Mean correlation | Average recovery accuracy | >= 0.90 |
| SD | Estimation variability | Low is better |
| CI width | Precision of estimates | Narrow is better |
| Prop above 90 | Power at r = 0.90 | >= 0.80 |
library(ggplot2)
ggplot(power_df, aes(x = n_sequences, y = mean_r)) +
geom_line() +
geom_point() +
geom_ribbon(aes(ymin = ci_lower, ymax = ci_upper), alpha = 0.2) +
geom_hline(yintercept = 0.90, linetype = "dashed", color = "red") +
labs(
x = "Number of Sequences",
y = "Mean Correlation with True Network",
title = "Power Analysis: Network Recovery by Sample Size"
) +
theme_minimal()Beyond correlation, examine edge recovery:
# For each sample size, calculate edge recovery
recovery_results <- lapply(sample_sizes, function(n) {
recoveries <- lapply(1:50, function(rep) {
seqs <- simulate_sequences(
trans_matrix = true_probs$transition_matrix,
init_probs = true_probs$initial_probs,
n_sequences = n,
seq_length = 25,
seed = rep * 1000 + n
)
model <- fit_network_model(seqs, "tna")
# Create pseudo-model from true matrix
true_model <- list(weights = true_probs$transition_matrix)
recovery <- compare_edge_recovery(
original = true_model,
simulated = model,
threshold = 0.05
)
c(precision = recovery$precision,
recall = recovery$recall,
f1 = recovery$f1_score)
})
df <- do.call(rbind, recoveries)
data.frame(
n_sequences = n,
precision_mean = mean(df[,"precision"]),
recall_mean = mean(df[,"recall"]),
f1_mean = mean(df[,"f1"])
)
})
recovery_df <- do.call(rbind, recovery_results)
print(recovery_df)Typically the most important factor:
Longer sequences provide more transitions:
# Compare different sequence lengths
length_grid <- generate_param_grid(
param_ranges = list(
n_sequences = c(50, 200),
seq_length = c(10, 50),
n_states = c(5, 5)
),
n = 30,
method = "lhs"
)
length_results <- run_grid_simulation(
param_grid = length_grid,
n_runs_per_setting = 30,
model_type = "tna",
seed = 42
)More states = more parameters to estimate:
# Compare different network sizes
states_grid <- generate_param_grid(
param_ranges = list(
n_sequences = c(50, 300),
seq_length = c(25, 25),
n_states = c(3, 10)
),
n = 30,
method = "lhs"
)
states_results <- run_grid_simulation(
param_grid = states_grid,
n_runs_per_setting = 30,
model_type = "tna",
seed = 42
)# 1. Define parameter space
full_grid <- generate_param_grid(
param_ranges = list(
n_sequences = c(25, 500),
seq_length = c(15, 40),
n_states = c(4, 8)
),
n = 100,
method = "lhs"
)
# 2. Run comprehensive simulation
full_results <- run_grid_simulation(
param_grid = full_grid,
n_runs_per_setting = 100,
model_type = "tna",
parallel = TRUE,
cores = parallel::detectCores() - 1,
seed = 42,
verbose = TRUE
)
# 3. Analyze results
analysis <- summarize_grid_results(full_results)
# 4. Generate power tables
power_table <- summarize_simulation(
full_results,
by = c("n_sequences", "seq_length", "n_states"),
metrics = c("mean", "sd", "ci_lower", "ci_upper")
)
# 5. Find recommended sample sizes
recommendations <- power_table[power_table$correlation_ci_lower >= 0.85, ]
min_by_condition <- aggregate(
n_sequences ~ seq_length + n_states,
data = recommendations,
FUN = min
)
print(min_by_condition)# Generate summary statistics
summary_stats <- summarize_simulation(
power_results,
by = "n_sequences",
metrics = "all"
)
# Create report
cat("
Power Analysis Results
=====================
Study Parameters:
- Sequence length: 25
- Number of states: 5
- Replications per condition: 100
- Target correlation: 0.90
Results by Sample Size:
")
print(summary_stats)
cat("
Recommendations:
- Minimum sample size for r >= 0.90:", min_n, "sequences
- Recommended sample size (with margin):", ceiling(min_n * 1.2), "sequences
")| Function | Purpose |
|---|---|
run_bootstrap_simulation() |
Bootstrap analysis |
run_bootstrap_iteration() |
Evaluate bootstrap results |
run_grid_simulation() |
Parameter grid simulation |
summarize_grid_results() |
Analyze grid output |
generate_param_grid() |
Create parameter combinations |
summarize_simulation() |
Summary statistics |
generate_param_grid()run_grid_simulation() with many replicationssummarize_grid_results() and
summarize_simulation()