How to transform data to have new minimum, maximum and average values?

6 views (last 30 days)
Hi all,
I have the following dataset with min = -6.3, max = 1.0 and mean = -3.3. Is there an easy way in matlab to transform these data to have a new minimum (-8.0), maximum (1.5) and mean (-2.9)? Thanks!
-5.0
-6.3
-4.6
-2.4
0.3
1.0
-4.7
-4.9
  4 Comments
Nadia Shaik
Nadia Shaik on 12 Oct 2022
Edited: Nadia Shaik on 12 Oct 2022
Hi Yoni,
To help me understand your query better, the following information is required:
  1. Sample Input
  2. Expected Ouput
dpb
dpb on 12 Oct 2022
This is really an unreasonable request when look at the input data at all...the original have a range from
Original Desired Difference
min = -6.3 -8.0 -1.7
max = 1.0 1.5 +0.5
mean= -3.3 -2.9 +1.4
It is expected to move the mean up by >1 while moving the minimum down by over 3X the amount of the adjustment upward on the high end. Just ain't agonna happen w/o a very strongly biased redistribution of the individual elements in the vector.
One would have to have something like a reverse Box-Cox transformation from more to less normal. It's surely possible could be made to happen, but just seems misguided.
That the OP never came back is somewhat telling it would seem, also.
x=[-5.0 -6.3 -4.6 -2.4 0.3 1.0 -4.7 -4.9];
subplot(3,1,1)
histfit(x)
subplot(3,1,2), hist(x), xlim([-8 2])
subplot(3,1,3), hist(rescale(x,-8,1.5))
The normality plot doesn't look so bad, but that's owing to the minimal number of points and the coarse binning; the actual distribution is pretty much at the ends alone...

Sign in to comment.

Answers (2)

Nadia Shaik
Nadia Shaik on 11 Oct 2022
Hi Yoni,
I understand that you want to transform existing data to have new minimum, maximum and mean values.
The minimum, maximum and mean values can be altered in an iterative way.
The following code snippet illustrates how to alter the parameters.
new_mean = 6;
new_min = -2;
new_max = 9;
error = 0.01;
x= [-5.0 -6.3 -4.6 -2.4 0.3 1.0 -4.7 -4.9];
while abs(new_mean - mean(x)) >= error
if new_mean > mean(x)
x(find(x < new_mean,1)) = randi([new_mean new_max]);
elseif new_mean < mean(x)
x(find(x > new_mean,1)) = randi([new_min new_mean]);
end
end
The above code will work accurately for large array sizes.
I hope this helps.
  1 Comment
dpb
dpb on 11 Oct 2022
That isn't a tranformation of the original dataset as asked for but the generation of a new dataset.
That may be ok, but is answer to a different Q? than the one posed by OP.

Sign in to comment.


dpb
dpb on 13 Oct 2022
OK, this has been rumbling around in back of head since posted -- one way that keeps the original dataset and adjusts them within the set bounds by tweaking each intermediate value after scaling...it's bizarre request, but does satisfy that --
x=[-5.0 -6.3 -4.6 -2.4 0.3 1.0 -4.7 -4.9].'; % sample data
MIN=-8.0; MAX=1.5; MEAN=-2.9; % target values
% the engine
[x,ix]=sort(x); % you'll see why here in a minute... :)
y=(rescale(x,MIN,MAX)); % scale first to min/max
N=numel(x); M=(N+1)/2; % median
dy=interp1([1 M N],[0 1 0],[1:N].'); % adjustment intermediate elements fixed endpoints
fnY=@(x)mean(y+x*dy);
dx=fsolve(@(x)abs(fnY(x))-abs(MEAN),0); % find the needed adjustment to hit new mean
Equation solved. fsolve completed because the vector of function values is near zero as measured by the value of the function tolerance, and the problem appears regular as measured by the gradient.
y=y+dx*dy; % the new vector values
y=y(ix); % and back in original order before adjustment
% show results
disp([min(y) max(y) mean(y)])
-8.0000 1.5000 -2.9000
subplot(3,1,1)
histfit(x), hold on, histfit(y)
subplot(3,1,2), hist(x), xlim([-8 2])
subplot(3,1,3), hist(y), xlim([-8 2])

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!