painful truncnorm
[This article was first published on Xi'an's Og » R, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
As I wanted to simulate truncated normals in a hurry, I coded the inverse cdf approach:
truncnorm=function(a,b,mu,sigma){ u=runif(1) u=qnorm(pnorm((a-mu)/sigma)*(1-u)+u*pnorm((b-mu)/sigma)) return(mu+sigma*u) }
instead of using my own accept-reject algorithm. Poor shortcut as the method fails when a and b are too far from μ
> truncnorm(1,2,3,4) [1] -0.4912926 > truncnorm(1,2,13,1) [1] Inf
So I introduced a control (and ended up wasting more time than if I had used my optimised accept-reject version!)
truncnorm=function(a,b,mu,sigma){ u=runif(1) if (pnorm((b-mu)/sigma)-pnorm((a-mu)/sigma)>0){ u=qnorm(pnorm((a-mu)/sigma)*(1-u)+u*pnorm((b-mu)/sigma)) }else{ u=-qnorm(pnorm(-(a-mu)/sigma)*(1-u)-u*pnorm(-(b-mu)/sigma))} return(mu+sigma*u) }
As shown by the above, it works, even when a=1, b=2 and μ=20. However, this eventually collapses as well and I ended up installing the msm R package that includes rtnorm, an R function running my accept-reject version. (This package was written by Chris Jackson from the MRC Unit in Cambridge.)
Filed under: R, Statistics Tagged: Monte Carlo Statistical Methods, msm package, quantile function, R, rtnorm function, simulation, truncated normal
To leave a comment for the author, please follow the link and comment on their blog: Xi'an's Og » R.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.