dt.scaled <- function(x, df, mean=0, sd=1, log=FALSE){
res <- dt((x-mean)/sd, df=df, log=log)
if(log){
res - log(sd)
}else{
res * 1/sd
}
}
inv_mills_ratio <- function(x, mu, sd){
sign(sd) * exp(dnorm(x, mu, abs(sd), log=TRUE) - invprobit(x, mu, sd, log=TRUE))
}
#' Inverse probit function
#'
#' Calculate the values of the sigmoidal function that is defined by the
#' cumulative normal distribution function (\code{\link{pnorm}}). This
#' method provides a convenient wrapper for the \code{pnorm} that automatically
#' handles negative zeta and is more consistent in its naming.
#'
#' @param x numeric vector
#' @param rho numeric vector of length 1 or the same length as x. Specifies
#' the inflection point of the inverse probit curve.
#' @param zeta numeric vector of length 1 or the same length as x. Specifies
#' the scale of the curve at the inflection point of the inverse probit curve.
#' @param log boolean if the log of the result is returned
#' @param oneminus boolean if one minus the result is returned
#'
#' @return a numeric vector of \code{length(x)}.
#' @examples
#' xg <- seq(-5, 5, length.out=101)
#' plot(xg, invprobit(xg, rho=-2, zeta=-0.3))
#' @export
invprobit <- function(x, rho, zeta, log=FALSE, oneminus=FALSE){
stopifnot(length(x) == length(rho) || length(rho) == 1 || length(x) == 1)
stopifnot(length(x) == length(zeta) || length(zeta) == 1 || length(x) == 1)
sign_sum <- sum(sign(zeta), na.rm=TRUE)
if(length(zeta) > 1 && abs(sign_sum) < sum(!is.na(zeta), na.rm=TRUE))
stop("All zeta must have the same sign")
if(sign_sum < 0){
pnorm(x, mean=rho, sd=-zeta, lower.tail = oneminus, log.p=log)
}else{
pnorm(x, mean=rho, sd=zeta, lower.tail = ! oneminus, log.p=log)
}
invprobit_fast(x, rho, zeta, log, oneminus)
}
#' Same thing as invprobit, but without the parameter validation
#'
#' @return a numeric vector of \code{length(x)}
#'
#' @keywords internal
invprobit_fast <- function(x, rho, zeta, log=FALSE, oneminus=FALSE){
sign_sum <- sum(sign(zeta), na.rm=TRUE)
if(sign_sum < 0){
pnorm(x, mean=rho, sd=-zeta, lower.tail = oneminus, log.p=log)
}else{
pnorm(x, mean=rho, sd=zeta, lower.tail = ! oneminus, log.p=log)
}
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.