# Continuous outcome, parallel CRT, equal clusters; base R only.
# Normal approximation SCREEN, not a final small-cluster power calculation.
d <- 0.35; m <- 25; alpha <- 0.05; target <- 0.80
n_ind <- 2*(qnorm(1-alpha/2)+qnorm(target))^2/d^2
icc <- c(0.01,0.03,0.05,0.10)
de <- 1+(m-1)*icc
clusters <- ceiling(n_ind*de/m)
print(data.frame(ICC=icc,design_effect=de,clusters_per_arm=clusters,people_per_arm=clusters*m),row.names=FALSE,quote=FALSE)
cat(sprintf('Individual-randomization normal approximation: %.2f per arm\n',n_ind))
# Participant attrition changes retained cluster size, not just total sample.
retained <- 20
cat(sprintf('At ICC=.05 and 20 retained per cluster: %d clusters per arm\n',ceiling(n_ind*(1+(retained-1)*.05)/retained)))
# Cluster loss must be allowed for separately.
cat(sprintf('For %d analyzable clusters/arm and 10%% cluster loss: recruit %d/arm\n',clusters[3],ceiling(clusters[3]/.90)))
stopifnot(all(diff(clusters)>=0))
