# How to weight observations to transform a distribution into normal?

Suppose X is a variable which follows some distribution (non normal) then how to define $$f(X(k))$$ (f is some functions of the variable X) such that

$$f(X)X$$ is normally distributed and $$0\leq f(X(k))\leq1$$ where $$k$$ shows observations.

Thanks

• Rank values from smallest to largest say $i = 1, \dots, N$ and then feed $(i - 0.5)/N$ to the normal quantile function in your favourite software. You need not think in terms of weights if your goal is just to transform a variable to approximately normal, come what may. (What you want to do about ties is an open question.) – Nick Cox Jan 16 '19 at 18:42

I've been spending so much time coding lately that it took me a minute to dust-off my pencil-and-paper statistics to figure this out.

Basically, your need $$f(X)$$ to be the ratio between your target Gaussian and the value of the X, matched by quantile.

You know the quantiles of any given gaussian ($$G$$) for the values of $$X$$ you observe: $$F_G^{-1}(X) \equiv w$$. Just divide this by the value of $$X$$ to get their ratio.

I don't understand the constraint about the weights being between zero and 1. I mean, you could divide the ratio by any number it make the weights smaller. It'll just affect the standard deviation of the gaussian that you're normalizing to.

Here's a simple example:

Here's a random empirical distribution super-imposed on a gaussian:

x <- log(1:100)
x <- x-mean(x)
plot(ecdf(x), xlim = c(-4,4))
lines(ecdf(rnorm(10000)), col = "red")

For every point in $$X$$, you need the ratio between your target gaussian and $$X$$, matched by quantile. Here's an example at the 95th quantile:

segments(x0 = qnorm(.95), x1 = quantile(x, .95), y0 = .95, col = "blue")

Basically, you divide the x position of the black line by the length of the blue line, for each point in your empirical distribution. Note that you've got to trim the gaussian in practice given that your data is finite.

w = qnorm(grid[2:(length(grid)-1)])/x
plot(ecdf(rnorm(10000)))
lines(ecdf(x*w), col = "red")

And there you are!