Revision 6b851464844d284b09d06c52a6d3d941b30162c3 authored by Wolfgang Viechtbauer on 08 May 2023, 10:30:02 UTC, committed by cran-robot on 08 May 2023, 10:30:02 UTC
1 parent d62321e
Raw File
transf.r
############################################################################

.chktargsint <- function(targs) {

   if (length(targs) > 3L)
      stop("Length of 'targs' argument must be <= 3.", call.=FALSE)

   if (.is.vector(targs)) {
      if (is.null(names(targs))) {
         names(targs) <- c("tau2", "lower", "upper")[seq_along(targs)]
         targs <- as.list(targs)
      } else {
         targs <- list(tau2=unname(targs[startsWith(names(targs), "t")]), lower=unname(targs[startsWith(names(targs), "l")]), upper=unname(targs[startsWith(names(targs), "u")]))
         targs <- targs[sapply(targs, length) > 0L]
      }
   }

   if (any(sapply(targs, length) > 1L))
      stop("Elements of 'targs' arguments must be scalars.", call.=FALSE)

   if (is.null(targs$tau2))
      targs$tau2 <- 0

   return(targs)

}

############################################################################

transf.rtoz <- function(xi) {                 ### resulting value between -Inf (for -1) and +Inf (for +1)
   xi[xi >  1] <-  1
   xi[xi < -1] <- -1
   atanh(xi)
}

transf.ztor <- function(xi)
   tanh(xi)

transf.ztor.int <- function(xi, targs=NULL) {

   if (is.na(xi))
      return(NA_real_)

   targs <- .chktargsint(targs)

   if (is.null(targs$lower))
      targs$lower <- xi-10*sqrt(targs$tau2)
   if (is.null(targs$upper))
      targs$upper <- xi+10*sqrt(targs$tau2)

   toint <- function(zval, xi, tau2)
      tanh(zval) * dnorm(zval, mean=xi, sd=sqrt(tau2))

   cfunc <- function(xi, tau2, lower, upper)
      integrate(toint, lower=lower, upper=upper, xi=xi, tau2=tau2)$value

   if (targs$tau2 == 0) {
      zi <- transf.ztor(xi)
   } else {
      zi <- mapply(xi, FUN=cfunc, tau2=targs$tau2, lower=targs$lower, upper=targs$upper)
   }

   return(c(zi))

}

############################################################################

transf.exp.int <- function(xi, targs=NULL) {

   if (is.na(xi))
      return(NA_real_)

   targs <- .chktargsint(targs)

   if (is.null(targs$lower))
      targs$lower <- xi-10*sqrt(targs$tau2)
   if (is.null(targs$upper))
      targs$upper <- xi+10*sqrt(targs$tau2)

   toint <- function(zval, xi, tau2)
      exp(zval) * dnorm(zval, mean=xi, sd=sqrt(tau2))

   cfunc <- function(xi, tau2, lower, upper)
      integrate(toint, lower=lower, upper=upper, xi=xi, tau2=tau2)$value

   if (targs$tau2 == 0) {
      zi <- exp(xi)
   } else {
      zi <- mapply(xi, FUN=cfunc, tau2=targs$tau2, lower=targs$lower, upper=targs$upper)
   }

   return(c(zi))

}

############################################################################

transf.logit <- function(xi)                       ### resulting value between -Inf (for 0) and +Inf (for +1)
   qlogis(xi)

transf.ilogit <- function(xi)
   plogis(xi)

transf.ilogit.int <- function(xi, targs=NULL) {

   if (is.na(xi))
      return(NA_real_)

   targs <- .chktargsint(targs)

   if (is.null(targs$lower))
      targs$lower <- xi-10*sqrt(targs$tau2)
   if (is.null(targs$upper))
      targs$upper <- xi+10*sqrt(targs$tau2)

   toint <- function(zval, xi, tau2)
      plogis(zval) * dnorm(zval, mean=xi, sd=sqrt(tau2))

   cfunc <- function(xi, tau2, lower, upper)
      integrate(toint, lower=lower, upper=upper, xi=xi, tau2=tau2)$value

   if (targs$tau2 == 0) {
      zi <- transf.ilogit(xi)
   } else {
      zi <- mapply(xi, FUN=cfunc, tau2=targs$tau2, lower=targs$lower, upper=targs$upper)
   }

   return(c(zi))

}

############################################################################

transf.arcsin <- function(xi)                      ### resulting value between 0 (for 0) and asin(1) = pi/2 (for 1)
   asin(sqrt(xi))

transf.iarcsin <- function(xi) {
   zi <- sin(xi)^2
   zi[xi < 0] <- 0                                 ### if xi value is below 0 (e.g., CI bound), return 0
   zi[xi > asin(1)] <- 1                           ### if xi value is above maximum possible value, return 1
   return(c(zi))
}

# transf.iarcsin.int <- function(xi, targs=NULL) {
#
#   if (is.na(xi))
#      return(NA_real_)
#
#   targs <- .chktargsint(targs)
#
#   if (is.null(targs$lower))
#      targs$lower <- 0
#   if (is.null(targs$upper))
#      targs$upper <- asin(1)
#
#   toint <- function(zval, xi, tau2)
#      transf.iarcsin(zval) * dnorm(zval, mean=xi, sd=sqrt(tau2))
#
#   cfunc <- function(xi, tau2, lower, upper)
#      integrate(toint, lower=lower, upper=upper, xi=xi, tau2=tau2)$value
#
#   if (targs$tau2 == 0) {
#      zi <- transf.iarcsin(xi)
#   } else {
#      zi <- mapply(xi, FUN=cfunc, tau2=targs$tau2, lower=targs$lower, upper=targs$upper)
#   }
#
#   return(c(zi))
#
# }

############################################################################

transf.pft <- function(xi, ni) {                   ### Freeman-Tukey transformation for proportions
   xi <- xi*ni
   zi <- 1/2*(asin(sqrt(xi/(ni+1))) + asin(sqrt((xi+1)/(ni+1))))
   return(c(zi))
}

transf.ipft <- function(xi, ni) {                  ### inverse of Freeman-Tukey transformation for individual proportions
   zi <- suppressWarnings(1/2 * (1 - sign(cos(2*xi)) * sqrt(1 - (sin(2*xi)+(sin(2*xi)-1/sin(2*xi))/ni)^2)))
   zi <- ifelse(is.nan(zi), NA_real_, zi)
   zi[xi > transf.pft(1,ni)] <- 1                  ### if xi is above upper limit, return 1
   zi[xi < transf.pft(0,ni)] <- 0                  ### if xi is below lower limit, return 0
   return(c(zi))
}

transf.ipft.hm <- function(xi, targs) {            ### inverse of Freeman-Tukey transformation for a collection of proportions
   if (is.null(targs) || (is.list(targs) && is.null(targs$ni)))
      stop("Must specify the sample sizes via the 'targs' argument.", call.=FALSE)
   if (is.list(targs)) {
      ni <- targs$ni
   } else {
      ni <- ni
   }
   nhm <- 1/(mean(1/ni, na.rm=TRUE))               ### calculate harmonic mean of the ni's
   zi <- suppressWarnings(1/2 * (1 - sign(cos(2*xi)) * sqrt(1 - (sin(2*xi)+(sin(2*xi)-1/sin(2*xi))/nhm)^2)))
   zi <- ifelse(is.nan(zi), NA_real_, zi)          ### it may not be possible to calculate zi
   zi[xi > transf.pft(1,nhm)] <- 1                 ### if xi is above upper limit, return 1
   zi[xi < transf.pft(0,nhm)] <- 0                 ### if xi is below lower limit, return 0
   return(c(zi))
}

############################################################################

transf.isqrt <- function(xi) {
   zi <- xi*xi
   zi[xi < 0] <- 0                                 ### if xi value is below 0 (e.g., CI bound), return 0
   return(c(zi))
}

############################################################################

transf.irft <- function(xi, ti) {                  ### Freeman-Tukey transformation for incidence rates
   zi <- 1/2*(sqrt(xi) + sqrt(xi + 1/ti))          ### xi is the incidence rate (not the number of events!)
   return(c(zi))
}

transf.iirft <- function(xi, ti) {                 ### inverse of Freeman-Tukey transformation for incidence rates (see Freeman-Tukey_incidence.r in code directory)
   #zi <- (1/ti - 2*xi^2 + ti*xi^4)/(4*xi^2*ti)    ### old version where transf.irft was not multiplied by 1/2
   zi <- (1/ti - 8*xi^2 + 16*ti*xi^4)/(16*xi^2*ti) ### xi is the incidence rate (not the number of events!)
   zi <- ifelse(is.nan(zi), NA_real_, zi)
   zi[xi < transf.irft(0,ti)] <- 0                 ### if xi is below lower limit, return 0
   zi[zi <= .Machine$double.eps] <- 0              ### avoid finite precision errors in back-transformed values (transf.iirft(transf.irft(0, 1:200), 1:200))
   return(c(zi))
}

############################################################################

transf.ahw <- function(xi) {                       ### resulting value between 0 (for alpha=0) and 1 (for alpha=1)
   #zi <- (1-xi)^(1/3)
   zi <- 1 - (1-xi)^(1/3)
   return(c(zi))
}

transf.iahw <- function(xi) {
   #zi <- 1-xi^3
   zi <- 1 - (1-xi)^3
   zi <- ifelse(is.nan(zi), NA_real_, zi)
   zi[xi > 1] <- 1                                 ### if xi is above upper limit, return 1
   zi[xi < 0] <- 0                                 ### if xi is below lower limit, return 0
   return(c(zi))
}

transf.abt <- function(xi) {                       ### Bonett (2002) transformation of alphas (without bias correction)
#transf.abt <- function(xi, ni) {                  ### resulting value between 0 (for alpha=0) to Inf (for alpha=1)
   #zi <- log(1-xi) - log(ni/(ni-1))
   #zi <- log(1-xi)
   zi <- -log(1-xi)
   return(c(zi))
}

transf.iabt <- function(xi) {                      ### inverse of Bonett (2002) transformation
#transf.iabt <- function(xi, ni) {
   #zi <- 1 - exp(xi) * ni / (ni-1)
   #zi <- 1 - exp(xi)
   zi <- 1 - exp(-xi)
   zi <- ifelse(is.nan(zi), NA_real_, zi)
   zi[xi < 0] <- 0                                 ### if xi is below lower limit, return 0
   return(c(zi))
}

############################################################################

transf.dtou1 <- function(xi) {
   u2i <- pnorm(abs(xi)/2)
   return((2*u2i - 1) / u2i)
}

transf.dtou2 <- function(xi)
   pnorm(xi/2)

transf.dtou3 <- function(xi)
   pnorm(xi)

transf.dtocles <- function(xi)
   pnorm(xi/sqrt(2))

transf.dtorpb <- function(xi, n1i, n2i) {
   if (missing(n1i) || missing(n2i)) {
      hi <- 4
   } else {
      if (length(n1i) != length(n2i))
         stop("Length of 'n1i' does not match length of 'n2i'.", call.=FALSE)
      if (length(n1i) != length(xi))
         stop("Length of 'n1i' and 'n2i' does not match length of 'xi'.", call.=FALSE)
      mi <- n1i + n2i - 2
      hi <- mi / n1i + mi / n2i
   }
   return(xi / sqrt(xi^2 + hi))
}

transf.dtobesd <- function(xi) {
   rpbi <- xi / sqrt(xi^2 + 4)
   return(0.50 + rpbi/2)
}

transf.dtomd <- function(xi, targs=NULL) {
   if (is.null(targs) || (is.list(targs) && is.null(targs$sd)))
      stop("Must specify a standard deviation value via the 'targs' argument.", call.=FALSE)
   if (is.list(targs)) {
      sd <- targs$sd
   } else {
      sd <- targs
   }
   if (length(sd) != 1L)
      stop("Specify a single standard deviation value via the 'targs' argument.", call.=FALSE)
   return(xi * sd)
}

transf.rtorpb <- function(xi, pi) {
   if (missing(pi)) {
      pi <- 0.5
   } else {
      if (length(pi) == 1L)
         pi <- rep(pi, length(xi))
      if (length(xi) != length(pi))
         stop("Length of 'xi' does not match length of 'pi'.", call.=FALSE)
   }
   if (any(pi < 0 | pi > 1, na.rm=TRUE))
      stop("One or more 'pi' values are < 0 or > 1.", call.=FALSE)
   return(xi * dnorm(qnorm(pi)) / sqrt(pi*(1-pi)))
}

transf.rtod <- function(xi, n1i, n2i) {
   if (missing(n1i) || missing(n2i)) {
      hi <- 4
      pi <- 0.5
      n1i <- 1
      n2i <- 1
   } else {
      if (length(n1i) != length(n2i))
         stop("Length of 'n1i' does not match length of 'n2i'.", call.=FALSE)
      if (length(n1i) != length(xi))
         stop("Length of 'n1i' and 'n2i' does not match length of 'xi'.", call.=FALSE)
      mi <- n1i + n2i - 2
      hi <- mi / n1i + mi / n2i
      pi <- n1i / (n1i + n2i)
   }
   if (any(c(n1i < 0, n2i < 0), na.rm=TRUE))
      stop("One or more values specified via the 'n1i' or 'n2i' arguments are negative.")
   rpbi <- xi * dnorm(qnorm(pi)) / sqrt(pi*(1-pi))
   return(sqrt(hi) * rpbi / sqrt(1 - rpbi^2))
}

transf.lnortord <- function(xi, pc) {
   if (length(pc) == 1L)
      pc <- rep(pc, length(xi))
   if (length(xi) != length(pc))
      stop("Length of 'xi' does not match length of 'pc'.", call.=FALSE)
   if (any(pc < 0) || any(pc > 1))
      stop("The control group risk 'pc' must be between 0 and 1.", call.=FALSE)
   return(exp(xi)*pc / (1 - pc + pc * exp(xi)) - pc)
}

transf.lnortorr <- function(xi, pc) {
   if (length(pc) == 1L)
      pc <- rep(pc, length(xi))
   if (length(xi) != length(pc))
      stop("Length of 'xi' does not match length of 'pc'.", call.=FALSE)
   if (any(pc < 0) || any(pc > 1))
      stop("The control group risk 'pc' must be between 0 and 1.", call.=FALSE)
   return(exp(xi) / (pc * (exp(xi) - 1) + 1))
}

############################################################################

transf.lnortod.norm <- function(xi)
   xi / 1.65

transf.lnortod.logis <- function(xi)
   sqrt(3) / base::pi * xi

transf.dtolnor.norm <- function(xi)
   xi * 1.65

transf.dtolnor.logis <- function(xi)
   xi / sqrt(3) * base::pi

transf.lnortortet.pearson <- function(xi)
   cos(base::pi / (1 + sqrt(exp(xi))))

transf.lnortortet.digby <- function(xi)
   (exp(xi)^(3/4) - 1) / (exp(xi)^(3/4) + 1)

############################################################################
back to top