R/n_fisher_boschloo.R

Defines functions .CritC_condS .CritfctXY .KX_Y .POW_EX_NR .Napprox_score .FINDSIZE .POW .CORRECTNOMLEV n_fisher_boschloo power_fisher_boschloo print.n_fisher_boschloo

Documented in n_fisher_boschloo power_fisher_boschloo

# I HELP FUNCTIONS==============================================================

#.CritC_condS

.CritC_condS <- function(M,N,alpha)  {

  RHO_0 <- 1
  NN <- M + N

  CritC <- matrix(0,NN+1,2)
  CritC[1,1] <- 0
  CritC[1,2] <- alpha
  for (S in 1:(NN-1))
  { X <- min(S,M)
  PX <- 1-pFNCHypergeo(X-1,M,N,S,RHO_0)
  while (PX <= alpha && X >= max(0,S-N)+1)
  { X <- X-1
  PX <- 1
  if (X > max(0,S-N))
    PX <- 1-pFNCHypergeo(X-1,M,N,S,RHO_0)  }
  C <- X
  PCPL <- 1-pFNCHypergeo(C,M,N,S,RHO_0)
  GAM <- (alpha-PCPL)/(PX-PCPL)
  CritC[S+1,1] <- C
  CritC[S+1,2] <- GAM    }
  CritC[NN+1,1] <- M
  CritC[NN+1,2] <- alpha
  return(CritC)
}

# Ende .CritC_condS

# .CritfctXY

.CritfctXY <- function(M,N,CritC)   {

  phi <- matrix(rep(0,((M+1)*(N+1))),ncol=N+1)
  for (x in 0:M)
  { for (y in 0:N)
  { s <- x+y
  if (x < CritC[s+1,1])
    phi[x+1,y+1] <- 0
  if (x == CritC[s+1,1])
    phi[x+1,y+1] <- CritC[s+1,2]
  if (x > CritC[s+1,1])
    phi[x+1,y+1] <- 1     }    }
  return(phi)
}

# Ende .CritfctXY

# .KX_Y

.KX_Y <- function(M,N,phi)   {

  kx_y <- c(rep(1,N+1))
  phi <- floor(phi)
  for (Y_ in 1:(N+1))
  { X_ <- 1
  while (phi[X_,Y_] == 0 && X_ <= M)
  { X_ <- X_+1  }
  kx_y[Y_] <- X_-1
  if (kx_y[Y_] == M && phi[M+1,Y_] == 0)
  { kx_y[Y_] <- M+1  }  }
  return(kx_y)
}

# Ende .KX_Y

# .POW_EX_NR

.POW_EX_NR <- function(M,N,kx_y,CritC,P1,P2)   {

  PBY <- c(rep(1,N+1))
  POWNR <- 0
  pi2 <- P2
  PBY[1] <- pbinom(0,N,pi2)
  for (Y_ in 2:(N+1))
  {  Y <- Y_-1
  PBY[Y_] <- pbinom(Y,N,pi2) - pbinom(Y-1,N,pi2)   }

  pi1 <- P1
  for (Y_ in 1:(N+1))
  { Y <- Y_-1
  if (kx_y[Y_] == 0) PBXGEK_Y <- 1
  if (kx_y[Y_] == M+1) PBXGEK_Y <- 0
  if (kx_y[Y_] >= 1 && kx_y[Y_] <= M)
  { PBXGEK_Y <- 1-pbinom(kx_y[Y_]-1,M,pi1)  }

  PBYEQY <- PBY[Y_]
  if (min(PBXGEK_Y,PBYEQY) <= 0) INCR <- 0
  if (min(PBXGEK_Y,PBYEQY) > 0)
  { LPBX <- log(PBXGEK_Y)
  LPBY <- log(PBYEQY)
  INCR <- exp(LPBX+LPBY)  }
  POWNR <- POWNR + INCR          }

  pow <- POWNR
  pow <- pow + CritC[1,2]*pbinom(0,M,pi1)*pbinom(0,N,pi2)
  NN <- M+N
  for (S in 1:NN)
  { x0 <- CritC[S+1,1]
  gam <- CritC[S+1,2]
  y0 <- S-x0
  pow <- pow + gam*(pbinom(x0,M,pi1)-pbinom(max(0,x0-1),M,pi1)*sign(x0)) *
    (pbinom(y0,N,pi2)-pbinom(max(0,y0-1),N,pi2)*sign(y0))  }
  pow_ex_nr <- matrix(c(0,0),ncol=2)
  pow_ex_nr[1,1] <- pow
  pow_ex_nr[1,2] <- POWNR
  return(pow_ex_nr)
}

# Ende .POW_EX_NR

.Napprox_score <- function(alpha,P1,P2,POW0,lambda) {


  p0 <- lambda*P1 + (1-lambda)*P2
  sig_H <- sqrt(p0*(1-p0)*(1/lambda + 1/(1-lambda)))
  sig_A <- sqrt(P1*(1-P1)/lambda + P2*(1-P2)/(1-lambda))
  napprox <- (sig_H*qnorm(1-alpha) + sig_A*qnorm(POW0))**2/(P1-P2)**2
  napprox <- ceiling(napprox)
  N1 <- round(lambda*napprox + 10**-6)
  N2 <- round((1-lambda)/lambda*N1 + 10**-6)
  Napprox <- matrix(c(0,0),ncol=2)
  Napprox[1,1] <- N1
  Napprox[1,2] <- N2
  return(Napprox)
}

# Ende .Napprox_score

# .FINDSIZE

.FINDSIZE <- function(M,N,SW,kx_y)      {

  PBY <- matrix(1,N+1,1)

  SIZE<-0
  SIZE_ <- 0
  PI2_ <- 0

  pi2<- 0

  while (pi2 <= 1 -SW) {
    pi2 <- pi2+SW
    pi1 <- pi2/(1-pi2)
    pi1 <- pi1/(1+pi1)
    PBY[1]=pbinom(0,N,pi2)
    for(Y_ in 2:(N+1)){
      Y<- Y_-1
      PBY[Y_]<- pbinom(Y,N,pi2) - pbinom(Y-1,N,pi2)
    }
    PROBRJ<-0

    for(Y_ in 1:(N+1))    {
      Y<- Y_-1
      if (kx_y[Y_]==0)   {
        PBXGEK_Y<-1   }

      if (kx_y[Y_]== M+1)   {
        PBXGEK_Y<-0   }
      if (kx_y[Y_] >= 1 & kx_y[Y_] <= M) {
        PBXGEK_Y<- 1-pbinom(kx_y[Y_]-1,M,pi1)}

      PBYEQY<- PBY[Y_]
      if (min(PBXGEK_Y,PBYEQY) <= 0) {
        INCR = 0  }
      if (min(PBXGEK_Y,PBYEQY) > 0) {
        LPBX<- log(PBXGEK_Y)
        LPBY<- log(PBYEQY)
        INCR<- exp(LPBX+LPBY) }
      PROBRJ<- PROBRJ+INCR }

    SIZE<-max(SIZE_,PROBRJ)
    if (SIZE > SIZE_) {
      SIZE_ <- SIZE
      PI2_ <- pi2 }
  }

  RESULTS_SIZE <- matrix(1,2,1)
  RESULTS_SIZE[1] <- SIZE
  RESULTS_SIZE[2] <- PI2_
  return(RESULTS_SIZE)
}

# Ende .FINDSIZE

# .POW

.POW <- function(M,N,kx_y,P1,P2) {

  PBY <- matrix(1,N+1,1)
  pow <- 0

  pi2 <- P2

  PBY[1] <- pbinom(0,N,pi2)

  for (Y_ in 2:(N+1))
  { Y <- Y_ - 1
  PBY[Y_] <- pbinom(Y,N,pi2) - pbinom(Y-1,N,pi2)  }

  pi1 <- P1

  for (Y_ in 1: (N+1))
  {
    Y <- Y_-1
    if (kx_y[Y_] == 0) PBXGEK_Y <- 1
    if (kx_y[Y_] == (M+1)) PBXGEK_Y <- 0
    if (kx_y[Y_] >= 1) PBXGEK_Y <- 1 - pbinom(kx_y[Y_]-1,M,pi1)

    PBYEQY <- PBY[Y_]

    if(min(PBXGEK_Y,PBYEQY) <= 0) INCR <- 0
    if(min(PBXGEK_Y,PBYEQY)  > 0)
    {
      LPBX <- log(PBXGEK_Y)
      LPBY <- log(PBYEQY)
      INCR <- exp(LPBX+LPBY)
    }

    pow <- pow + INCR
  }

  return(pow)

}

# Ende .POW

# .CORRECTNOMLEV

.CORRECTNOMLEV <- function(M,N,alpha,SW,MAXH) {

  CritC <- .CritC_condS(M,N,alpha)
  phi <- .CritfctXY(M,N,CritC)
  kx_y <- .KX_Y(M,N,phi)

  RES_SIZE <- .FINDSIZE(M,N,SW,kx_y)
  SIZE_UNC <- RES_SIZE[1]

  alpha2 <- alpha
  SIZE <- SIZE_UNC

  while(SIZE <= alpha)
  {
    alpha2 <- alpha2 + .01
    CritC <- .CritC_condS(M,N,alpha2)
    phi <- .CritfctXY(M,N,CritC)
    kx_y <- .KX_Y(M,N,phi)

    RES_SIZE <- .FINDSIZE(M,N,SW,kx_y)
    SIZE <- RES_SIZE[1]
  }

  alpha1 <- alpha2 - .01
  IT <- 0

  while(IT <= MAXH)
  {
    alpha0 <- (alpha1+alpha2) / 2
    IT <- IT + 1
    CritC <- .CritC_condS(M,N,alpha0)
    phi <- .CritfctXY(M,N,CritC)
    kx_y <- .KX_Y(M,N,phi)

    RES_SIZE <- .FINDSIZE(M,N,SW,kx_y)
    SIZE <- RES_SIZE[1]

    if(SIZE < alpha)
    {
      alpha1 <- alpha0
      SIZE1 <- SIZE
    }     else

      alpha2 <- alpha0
  }

  alpha0 <- alpha1
  SIZE0 <- SIZE1

  phi_final <- .CritfctXY(M,N,CritC)
  kx_y_final <- .KX_Y(M,N,phi)

  CORRNLres <- matrix(0,1,3)
  CORRNLres[1] <- alpha0
  CORRNLres[2] <- SIZE0
  CORRNLres[3] <- SIZE_UNC

  return(CORRNLres)

}

# Ende .CORRECTNOMLEV

# II SAMPLE SIZE FUNCTION=======================================================

#' Sample Size Calculation for the Fisher-Boschloo-Test
#'
#' \code{n_fisher_boschloo} performs the Sample Size calculation for two
#'   independent samples with binary data using the absolute rate
#'   difference quantifying the effect of an intervention.
#'   The method used here is written by S. Wellek.
#'   See [2] for further details.
#'
#' \describe{
#'   \item{Null Hypothesis:}{\eqn{p_Y - p_X = 0}}
#'   \item{Alternative Hypothesis:}{\eqn{|p_Y - p_X| \ge \Delta_A}}
#' }
#'
#' @param p_Y         Event rate of Group Y on the alternative.
#' @param p_X         Event rate of Group X on the alternative.
#' @param alpha       Significance level \eqn{\alpha}.
#' @param power       Desired Power \eqn{1-\beta}.
#' @param r           Quotient of Sample sizes \eqn{r = n_Y / n_X}.
#' @param exact Default = TRUE. If set to FALSE the approximative
#'   sample size is calculated. On TRUE the exact sample size is calculated.
#' @param SW          Default = .0001. Step width.
#' @param MAXH        Default = 10.
#'
#' @return \code{n_fisher_boschloo} returns an object of type list. The resulting
#'   Sample Sizes are located in entrys named \code{n_X}, \code{n_Y}, \code{n}.
#'   The resulting power is named \code{power_out}.
#'
#' @examples
#' n_fisher_boschloo(p_Y = .5, p_X = .3, alpha = .05, power = .8, r = 2)
#' n_fisher_boschloo(p_Y = .5, p_X = .3, alpha = .05, power = .8, r = 2)$n
#' n_fisher_boschloo(p_Y = .5, p_X = .3, alpha = .05, power = .8, r = 2, exact = FALSE)
#'
#' @details [2] S. Wellek: Nearly exact sample size calculation for powerful
#' non-randomized tests for differences between binomial proportions [2015],
#' Statistica Neerlandica

n_fisher_boschloo <- function(p_Y, p_X, alpha, power, r, exact = TRUE, SW = .0001, MAXH = 10) {

  mton_a <- .get_fraction(r)$numerator
  mton_b <- .get_fraction(r)$denominator
  if ( (r %% 1) == 0 ) {mton_b <- 1}
  P1 <- p_Y
  P2 <- p_X
  POW0 <- power

  #cat(" ALPHA = ", alpha, " SW = ", SW, " MAXH = ", MAXH,
  #    "\n","\n","P1 = ", P1," P2 = ", P2," POW0 = ", POW0," mton_a = ", mton_a," mton_b = ", mton_b,
  #    file="boschloo_output.txt", append=FALSE)

  mton_ab <- mton_a + mton_b
  lambda <- mton_a/mton_ab

  Nstart <- .Napprox_score(alpha,P1,P2,POW0,lambda)
  M <- Nstart[1,1]
  N <- Nstart[1,2]
  M <- round((M+N)/mton_ab + 10**-6) * mton_a
  N <- round((M+N)/mton_ab + 10**-6) * mton_b

  CritC <- .CritC_condS(M,N,alpha)
  phi <- .CritfctXY(M,N,CritC)
  kx_y <- .KX_Y(M,N,phi)
  pow_ex_nr <- .POW_EX_NR(M,N,kx_y,CritC,P1,P2)
  POWEX <- pow_ex_nr[1,1]

  mstart <- M
  nstart <- N

  #cat("\n","\n","mstart = ",mstart," nstart = ", nstart,"\n","\n","POW_EX_NR = ", pow_ex_nr,
  #    file="boschloo_output.txt", append=TRUE)

  incr_m <- mton_a
  incr_n <- mton_b
  incr5_m <- 5*incr_m
  incr5_n <- 5*incr_n

  if (POWEX < POW0)
  {
    repeat
    {
      M <- M + incr5_m
      N <- N + incr5_n
      CritC <- .CritC_condS(M,N,alpha)
      phi <- .CritfctXY(M,N,CritC)
      kx_y <- .KX_Y(M,N,phi)
      pow_ex_nr <- .POW_EX_NR(M,N,kx_y,CritC,P1,P2)
      POWEX <- pow_ex_nr[1,1]
      if(POWEX >= POW0) break
    }

    M <- M - incr5_m
    N <- N - incr5_n

    repeat
    {
      M <- M + incr_m
      N <- N + incr_n
      CritC <- .CritC_condS(M,N,alpha)
      phi <- .CritfctXY(M,N,CritC)
      kx_y <- .KX_Y(M,N,phi)
      pow_ex_nr <- .POW_EX_NR(M,N,kx_y,CritC,P1,P2)
      POWEX <- pow_ex_nr[1,1]
      if(POWEX >= POW0) break
    }
  } else

  {
    repeat
    {
      M <- M - incr5_m
      N <- N - incr5_n
      CritC <- .CritC_condS(M,N,alpha)
      phi <- .CritfctXY(M,N,CritC)
      kx_y <- .KX_Y(M,N,phi)
      pow_ex_nr <- .POW_EX_NR(M,N,kx_y,CritC,P1,P2)
      POWEX <- pow_ex_nr[1,1]
      if(POWEX < POW0) break
    }

    repeat
    {
      M <- M + incr_m
      N <- N + incr_n
      CritC <- .CritC_condS(M,N,alpha)
      phi <- .CritfctXY(M,N,CritC)
      kx_y <- .KX_Y(M,N,phi)
      pow_ex_nr <- .POW_EX_NR(M,N,kx_y,CritC,P1,P2)
      POWEX <- pow_ex_nr[1,1]
      if(POWEX >= POW0) break
    }
  }

  Mex <- M
  Nex <- N
  #cat("\n","\n","Mex = ",Mex," Nex = ",Nex," POWEX = ", POWEX,
  #    file="boschloo_output.txt", append=TRUE)

  POWNR <- pow_ex_nr[1,2]

  mstart <- Mex
  nstart <- Nex

  if(POWNR < POW0)
  {
    repeat
    {
      M <- M + incr5_m
      N <- N + incr5_n
      CritC <- .CritC_condS(M,N,alpha)
      phi <- .CritfctXY(M,N,CritC)
      kx_y <- .KX_Y(M,N,phi)
      pow_ex_nr <- .POW_EX_NR(M,N,kx_y,CritC,P1,P2)
      POWNR <- pow_ex_nr[1,2]
      if(POWNR >= POW0) break
    }

    M <- M - incr5_m
    N <- N - incr5_n

    repeat
    {
      M <- M + incr_m
      N <- N + incr_n
      CritC <- .CritC_condS(M,N,alpha)
      phi <- .CritfctXY(M,N,CritC)
      kx_y <- .KX_Y(M,N,phi)
      pow_ex_nr <- .POW_EX_NR(M,N,kx_y,CritC,P1,P2)
      POWNR <- pow_ex_nr[1,2]
      if(POWNR >= POW0) break
    }
  } else

  {
    repeat
    {
      M <- M - incr5_m
      N <- N - incr5_n
      CritC <- .CritC_condS(M,N,alpha)
      phi <- .CritfctXY(M,N,CritC)
      kx_y <- .KX_Y(M,N,phi)
      pow_ex_nr <- .POW_EX_NR(M,N,kx_y,CritC,P1,P2)
      POWNR <- pow_ex_nr[1,2]
      if(POWNR < POW0) break
    }

    repeat
    {
      M <- M + incr_m
      N <- N + incr_n
      CritC <- .CritC_condS(M,N,alpha)
      phi <- .CritfctXY(M,N,CritC)
      kx_y <- .KX_Y(M,N,phi)
      pow_ex_nr <- .POW_EX_NR(M,N,kx_y,CritC,P1,P2)
      POWNR <- pow_ex_nr[1,2]
      if(POWNR >= POW0) break
    }
  }

  Mnr <- M
  Nnr <- N
  #cat("\n","\n","Mnr = ",Mnr,"Nnr = ", Nnr," POWNR = ", POWNR,
  #    file="boschloo_output.txt", append=TRUE)

  m0 <- (Mex + Mnr)/2
  n0 <- (Nex + Nnr)/2
  M <- round((m0+n0)/mton_ab)*mton_a
  N <- round((m0+n0)/mton_ab)*mton_b

  CORRNOMLEV <- .CORRECTNOMLEV(M,N,alpha,SW,MAXH)

  alpha0 <- CORRNOMLEV[1,1]
  CritC <- .CritC_condS(M,N,alpha0)
  phi <- .CritfctXY(M,N,CritC)
  kx_y <- .KX_Y(M,N,phi)
  pow <- .POW(M,N,kx_y,P1,P2)
  pow_approx <- pow

  mstart <- M
  nstart <- N
  #cat("\n","\n","MStart = ",mstart," NStart = ", nstart," alpha0 = ", alpha0," POW = ", pow,
  #    file="boschloo_output.txt", append=TRUE)

  incr_m <- mton_a
  incr_n <- mton_b
  incr5_m <- 2*incr_m
  incr5_n <- 2*incr_n

  if(pow < POW0)
  {
    repeat
    {
      M <- M + incr5_m
      N <- N + incr5_n
      CORRNOMLEV <- .CORRECTNOMLEV(M,N,alpha,SW,MAXH)
      alpha0 <- CORRNOMLEV[1,1]
      SIZE <- CORRNOMLEV[1,2]
      CritC <- .CritC_condS(M,N,alpha0)
      phi <- .CritfctXY(M,N,CritC)
      kx_y <- .KX_Y(M,N,phi)
      pow <- .POW(M,N,kx_y,P1,P2)
      if(pow >= POW0) break
    }

    M <- M - incr5_m
    N <- N - incr5_n

    repeat
    {
      M <- M + incr_m
      N <- N + incr_n
      CORRNOMLEV <- .CORRECTNOMLEV(M,N,alpha,SW,MAXH)
      alpha0 <- CORRNOMLEV[1,1]
      SIZE <- CORRNOMLEV[1,2]
      CritC <- .CritC_condS(M,N,alpha0)
      phi <- .CritfctXY(M,N,CritC)
      kx_y <- .KX_Y(M,N,phi)
      pow <- .POW(M,N,kx_y,P1,P2)
      if(pow >= POW0) break
    }
  }  else

  {
    repeat
    {
      M <- M - incr5_m
      N <- N - incr5_n
      CORRNOMLEV <- .CORRECTNOMLEV(M,N,alpha,SW,MAXH)
      alpha0 <- CORRNOMLEV[1,1]
      SIZE <- CORRNOMLEV[1,2]
      CritC <- .CritC_condS(M,N,alpha0)
      phi <- .CritfctXY(M,N,CritC)
      kx_y <- .KX_Y(M,N,phi)
      pow <- .POW(M,N,kx_y,P1,P2)
      if(pow < POW0) break
    }

    repeat
    {
      M <- M + incr_m
      N <- N + incr_n
      CORRNOMLEV <- .CORRECTNOMLEV(M,N,alpha,SW,MAXH)
      alpha0 <- CORRNOMLEV[1,1]
      SIZE <- CORRNOMLEV[1,2]
      CritC <- .CritC_condS(M,N,alpha0)
      phi <- .CritfctXY(M,N,CritC)
      kx_y <- .KX_Y(M,N,phi)
      pow <- .POW(M,N,kx_y,P1,P2)
      if(pow >= POW0) break
    }
  }

  MBo <- M
  NBo <- N

  #cat("\n","\n","MBo = ",MBo," NBo = ", NBo," alpha0 = ", alpha0," SIZE = ", SIZE," POW = ", pow,
  #    file="boschloo_output.txt", append=TRUE)

  #file.show("boschloo_output.txt")

  # Organize Output for presentation
  if (exact == TRUE){
    n_Y = MBo
    n_X = NBo
    n   = n_Y + n_X
    power_out = pow
  } else {
    n_Y = mstart
    n_X = nstart
    n   = n_Y + n_X
    power_out = pow_approx
  }

  n.results <- list(
    n_X = n_X,
    n_Y = n_Y,
    n   = n_X + n_Y,
    power_out = power_out
  )

  input_list <- list(
   alpha = alpha,
   power = power,
   exact = exact,
   r   = r,
   p_Y = p_Y,
   p_X = p_X,
   SW = SW
  )

  results         <- c(input_list, n.results)
  class(results)  <- c("n_fisher_boschloo", class(results))

  return(results)

}

# III POWER FUNCTION============================================================

#' Power Calculation for the Fisher-Boschloo-Test
#'
#' \code{power_fisher_boschloo} performs the exact power calculation for the
#'   fisher-boschloo test.
#'   The method used here is written by S. Wellek.
#'   See [2] for further details.
#'
#' @param p_Y         Event rate of Group Y on the alternative.
#' @param p_X         Event rate of Group X on the alternative.
#' @param n_Y         Sample size of Group Y.
#' @param n_X         Sample size of Group X.
#' @param alpha       Significance level \eqn{\alpha}.
#' @param SW          Default = .001. Step width.
#' @param MAXH        Default = 10.
#'
#' @return \code{n_fisher_boschloo} returns an object of type list. The resulting
#'   Sample Sizes are located in entrys named \code{n_X}, \code{n_Y}, \code{n}.
#'   The resulting power is named \code{power_out}.
#'
#' @examples
#' power_fisher_boschloo(p_Y = .5, p_X = .3, n_Y = 70, n_X = 40, alpha = .025)
#'
#' @details [2] S. Wellek: Nearly exact sample size calculation for powerful
#' non-randomized tests for differences between binomial proportions [2015],
#' Statistica Neerlandica


power_fisher_boschloo <- function(p_Y, p_X, n_Y, n_X, alpha,
  SW = .0001,
  MAXH = 10
){
  CORRNOMLEV <- .CORRECTNOMLEV(n_Y, n_X, alpha, SW, MAXH)
  alpha0     <- CORRNOMLEV[1,1]
  SIZE       <- CORRNOMLEV[1,2]
  CritC      <- .CritC_condS(n_Y, n_X, alpha0)
  phi        <- .CritfctXY(n_Y, n_X, CritC)
  kx_y       <- .KX_Y(n_Y, n_X, phi)
  pow        <- .POW(n_Y, n_X, kx_y, p_Y, p_X)
# retrn power
  return(pow)
}

#IV PRINT FUNCTION==============================================================

print.n_fisher_boschloo <- function(x, ...){

  cat("Sample size calculation for the Fisher-Boschloo test for two independent\n")
  cat("samples with binary data using the absolute rate difference.\n")
  if(x$exact == TRUE) {cat("Exact calculation performed. \n\n")}
  else {cat("Approximative calculation performed. \n\n")}

  cat(sprintf(
    "Input Parameters \n
Rate intervention group : %.3f
Rate control group : %.3f
Significance level : %.4f
Desired power : %.2f %%
Step width : %.4f
Allocation : %.2f \n
Results of sample size calculation \n
n intervention group : %i
n control group : %i
n total : %i
Actual power : %.5f %%",

    x$p_Y,
    x$p_X,
    x$alpha,
    x$power*100,
    x$SW,
    x$r,
    x$n_Y,
    x$n_X,
    x$n,
    x$power_out*100
  )
  )

}
goseberg/samplesizr documentation built on May 28, 2019, 8:43 a.m.