tafelplankje
tafelplankje

Reputation: 593

Convert P to Z in log space

Given a -log10(P) value, I'd like to calculate the Z score in log space, how would I do that?

So, given the following code, how to recode the last line so that it calculates Z from log10P in the log space?

Z=10
log10P  = -1*(pnorm(-abs(Z),log.p = T)*1/log(10) + log10(2))
Z== -1*(qnorm(10^-log10P/2)) # <- this needs to be in log space. 

Upvotes: 3

Views: 260

Answers (1)

Ben Bolker
Ben Bolker

Reputation: 226801

qnorm also has a log.p argument analogous to pnorm's, so you can reverse the operations that you used to get log10P in the first place (it took me a couple of tries to get this right ...)

I rearranged your log10P calculation slightly.

log10P_from_Z <- function(Z) {
    abs((pnorm(-abs(Z),log.p=TRUE)+log(2))/log(10))
}
Z_from_log10P <- function(log10P) {
    -1*qnorm(-(log10P*log(10))-log(2), log.p=TRUE)
}

We can check the round-trip accuracy (i.e. convert from -log10(p) to Z and back, see how close we got to the original value.) This works perfectly for values around 20, but does incur a little bit of round-off error for large values (would have to look more carefully to see if there's anything that can be remedied here).

zvec <- seq(20,400)
err <- sapply(zvec, function(z) {
   abs(Z_from_log10P(log10P_from_Z(z))-z)
})

curve of round-trip error, log scale; rises from 0 to ~ 1e-4

Upvotes: 4

Related Questions