cfdr for functional annotations

Jamesโ€™ vlyl() function uses KDEs to approximate the cfdr and find L curves.

This is done in a two-step approach:

  1. Find the ccut values where ccut[i]=cfdr(p[i],q[i]) (fixing q to generate the cfdr curves)

  2. Find the xval2 values where cfdr(xval2[i,j], yval2[i,j])=ccut[i] (fixing yval2 to generate cfdr curves)

cfdr is estimated by cgrid and this is interpolated to find ccut and xval2.

1. cfdr

cgrid estimates the adjusted cfdr by

\[\begin{equation} \begin{split} \hat{cFDR} &= P(H_0^p\text{ | }P\leq p, Q\leq q)\\[2ex] &= \dfrac{P(P\leq p\text{ | }H_0^p, Q\leq q) P(H_0^p\text{ | }Q\leq q)}{P(P\leq p \text{ | }Q\leq q)}\\[2ex] &= \dfrac{P(P\leq p\text{ | }H_0^p) \times \dfrac{P(Q\leq q\text{ | }H_0^p) P(H_0^p)}{P(Q\leq q)}}{\dfrac{P(P\leq p , Q\leq q)}{P(Q\leq q)}}\\[2ex] &\approx \dfrac{P(P\leq p\text{ | }H_0^p) \times P(Q\leq q\text{ | }H_0^p)}{P(P\leq p, Q\leq q)}\\[2ex] &\approx \dfrac{P(P\leq p, Q\leq q\text{ | }H_0^p)}{P(P\leq p, Q\leq q)}. \end{split} \end{equation}\]

Estimating \(P(P\leq p, Q\leq q)\)

We first estimate \(P(P\leq p, Q\leq q)\) (the denominator) using KDE:

# P,Q
kpq = kde2d(c(zp[sub],zp[sub],-zp[sub],-zp[sub]),c(zq[sub],-zq[sub],-zq[sub],zq[sub]), n=res, lims=lims, h=c(1,1))
kpq$z = apply(kpq$z, 2, function(x) rev(cummax(rev(x)))) # ensures non-increasing

The second line ensures that it is non-increasing - see below for an example:

Estimating \(P(P\leq p, Q\leq q\text{ | }H_0^p)\)

We then use the independence assumption to estimate \(P(P\leq p, Q\leq q\text{ | }H_0^p)=P(P\leq p|H_0^p) \times P(Q\leq q|H_0^p)\) (the numerator):

# Q | H_0
kq = density(c(zq[sub][which(p[sub]>0.5)],-zq[sub][which(p[sub]>0.5)]), from=lims[1], to=lims[2], n=res)

# P | H_0
px = dnorm(seq(lims[1], lims[2], length.out=res))

# P,Q | H_0
kpq0 = kpq 
kpq0$z = outer(px, kq$y) # P|H0 * Q|H0
kpq0$z = kpq0$z*(sum(kpq$z)/sum(kpq0$z)) # ensure sum(kpq$z)=sum(kpq0$z) 

kpq$z[which(kpq$z==0)] = min(kpq$z[which(kpq$z>0)])
kpq0$z[which(kpq0$z==0)] = min(kpq0$z[which(kpq0$z>0)])