MATLAB Answers

MRC
0

How to pick the j-th percentile of a vector?

Asked by MRC
on 2 May 2014
Latest activity Commented on by Siddhartha on 7 Apr 2016
Hi, I have a matrix A nx1, e.g.
A=randn(200,1);
II want to pick the element of A which is the 25th percentile above the minimum in A. How can I do it?

  2 Comments

What does that mean?
function val = SpecialPercentile(arr, pct)
len = length(arr);
ind = floor(pct/100*len);
newarr = sort(arr);
val = newarr(ind);
end
Then call this function p = SpecialPercentile(A, 25);

Sign in to comment.

3 Answers

Answer by Star Strider
on 2 May 2014
 Accepted Answer

If you don’t have the Statistics Toolbox, this doesn’t replicate the prctile results exactly, but it’s close:
pctl = @(v,p) interp1(linspace(0.5/length(v), 1-0.5/length(v), length(v))', sort(v), p*0.01, 'spline');
where v is the data vector and p is the percentile. You would call it as:
p = pctl(A, 25);
in your example.

  0 Comments

Sign in to comment.


Answer by Justin
on 2 May 2014
Edited by Justin
on 2 May 2014

Is the function prctile what you are looking for?
It is in the statistics toolbox. You can use it to find the specific percentile you are looking for (in this case 25) and then find the minimum element in A greater than the percentile number.
Let me know if this makes sense or if you would like an example.

  0 Comments

Sign in to comment.


Answer by Image Analyst
on 2 May 2014

Do you mean like this:
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 30;
A=randn(200,1);
sortedA = sort(A)
minA = min(A) % Just for information - not used
% Get cumulative distribution function
cdf = cumsum(sortedA - sortedA(1))
bar(cdf);
% Normalize
normalizedCdf = cdf / cdf(end)
% Plot it.
plot(sortedA,normalizedCdf, 'LineWidth', 2); % Show in plot.
grid on;
title('Cumulative Distribution Function', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
% Find index where it exceeds 25% for the first time
indexOf25Percentile = find(normalizedCdf > 0.25, 1, 'first')
% Find value where it exceeds 25% for the first time
valueOf25Percentile = sortedA(indexOf25Percentile)
% Plot vertical bar there
line([valueOf25Percentile, valueOf25Percentile], [0, .25],...
'Color', 'r', 'LineWidth', 2);
% Plot horizontal bar there
xl = xlim;
line([xl(1), valueOf25Percentile], [0.25, .25],...
'Color', 'r', 'LineWidth', 2);
message = sprintf('25 Percentile happens at %f (index %d)',...
valueOf25Percentile, indexOf25Percentile);
uiwait(msgbox(message));

  4 Comments

Show 1 older comment
What do you mean by percentile? I mean like the percentile you'd get if you took the histogram and cdf, so it comes from the frequency of occurrence. Yours goes based strictly on the number of elements and ignores what the values are, which seems strange. So you're always taking the 50th element regardless of what that element's value is or how the values are distributed. That's not the definition of percentile that most people use.
Let's say you have a collection of animal weights. Let's say you have 55 ants, and 145 elephants. Your method would sort them and take the weight of the 50th animal, which would be an ant. So you'd say that the 50th weight percentile was 3 milligrams. My method would look at the weight to find where 50% of the weight was less and 50% of the weight was more. That of course would lie with the elephants, probably at the 73rd elephant, and so my method would give the 50th percentile weight at 5000 kilograms.
Which way do you want it?
Well, I have just applied this definition http://en.wikipedia.org/wiki/Percentile section nearest rank
I'm not sure why your value should be different
You can do it that way if you want. It's like I'm taking the rank of the y values and you're taking the rand of the x values. Notice on the red lines that my 25% is 25% of the y (which happens at an x of -0.17), and yours would be the 25% of the x (-2.25) and you'd read off the y that you get at x = -2.25 (which is like 0.01 or something). If the cdf is linear, like you'd get with a uniform distribution, then they'll give the same value. If not, then they'll be different.

Sign in to comment.