The following code in R was my attempt of to solve the problem of finding an algorithm to convert a vector of values to a new vector of values with mean of 0 and range of [-1, 1].
After one pass, it doesn't quite work. (The result will have the specified range, but the mean will be off-zero, though usually not by too much).
However, it appears that if it's applied iteratively (feeding the results back through the algorithm), it will reach the desired result within a certain tolerance.
I doubt this transformation is practically useful. And one could probably come up with a simpler process to arrive at a similar result.
Briefly, it centers A on mean of 0, and then divides this new A_center into those values above and below 0 (A1 and A2), adds a value of precisely 0 to each, and then applies a linear transformation to each of these to fit a range of [-1, 0] and [0, 1].
### RUN THIS ONCE, WITH A AS THE INPUT VECTOR ###
A = c(1,2,2,3,3,3,4,4,4,4,5,5,5,5,5,8,8,8,8,8,8,8,8,8,8,8)
A_trans = A
### RUN THIS ITERATIVELY UNTIL THE RESULTS ARE WITHIN TOLERANCE ###
A = A_trans
hist(A)
A_center = A - mean(A)
A1 = c(0, A_center [A_center < 0])
A2 = c(0, A_center [A_center > 0])
A1_scaled = ((A1 - min(A1) * (0 - -1))/(max(A1) - min(A1)) + -1)
A2_scaled = ((A2 - min(A2) * (1 - 0))/(max(A2) - min(A2)) + 0)
A_trans = c(A1_scaled[2:length(A1_scaled)], A2_scaled[2:length(A2_scaled)])
hist(A_trans)
Sum=data.frame(
N = c(length(A),length(A_center),length(A_trans)),
Mean = c(round(mean(A), 2), round(mean(A_center), 2), round(mean(A_trans), 2)),
Min = c(round(min(A), 2), round(min(A_center), 2), round(min(A_trans), 2)),
Max = c(round(max(A), 2), round(max(A_center), 2), round(max(A_trans), 2)),
CountLess0 = c(sum(A < 0),sum(A_center < 0),sum(A_trans < 0)),
CountGreater0 = c(sum(A > 0),sum(A_center > 0),sum(A_trans > 0)),
row.names=c("A", "A_center", "A_trans")
)
Sum