No BSD License  

Highlights from
Bootstrap a statistic in a grouped sample

image thumbnail
bstrag(b,fun,c,x,varargin)
function[res] = bstrag(b,fun,c,x,varargin)
% BSTRAG     Bootstrap a statistic in a grouped sample 
% INPUTS   : b      - number of bootstrap samples 
%            fun    - name of function computing desired statistic(s), with
%                     output  placed in p*q array  or structure. Input argu-
%                     ments are  passed to  fun  in the order in which they
%                     appear in bstrag(..);  thus, fun must have c and x as
%                     arguments 1 and 2.
%            c      - n*1 grouping vector,  with c(i)  identifying the group
%                     of ith row of x(,y,z,..). Any non-NaN values are accep-
%                     table; groups are identified by  distinct values in c.
%                     RESAMPLING IS CONDUCTED SEPARATELY FOR EACH GROUP;  if
%                     group m includes  k rows of x(,y,z,..), any  bootstrap
%                     sample will include k randomly selected rows belonging
%                     to it.
%            x      - n*k data matrix, with observations in rows
%            y,z,.. - (optional) additional  vectors/matrices, referenced by
%                     fun, including  scalars. Input arguments are passed to
%                     fun in the  order  they appear in bstrag(..). Non-sca-
%                     lar inputs must have the same number of rows as x.
% OUTPUTS  : res    - statistic values in original and constructed samples
%                     p*q*(b+1) array if fun outputs an array 
%                     1*(b+1) structure array if fun outputs a structure 
%                     First element of res contains value of fun, computed 
%                     in the actual sample.
% EXAMPLE  : See BSTRAG_DEMO 
% SEE ALSO : BSTRAP, BSTATS; JACKKNIFE, BOOTSTRP (Statistics Toolbox)
% AUTHOR   : Dimitri Shvorob, dimitri.shvorob@vanderbilt.edu, 3/25/07

if nargin < 1
   error('Input argument "b" is undefined')
end
if nargin < 2
   error('Input argument "fun" is undefined') 
end    
if nargin < 3    
   error('Input argument "c" is undefined')
end
if nargin < 4    
   error('Input argument "x" is undefined')
end
if ~isnumeric(b)
   error('Input argument "b" must be numeric')
end  
if b ~= floor(b) 
   error('Input argument "b" must be an integer')
end
if b <= 0
   error('Input argument "b" must be positive')
end
if ~ischar(fun)
   error('Input argument "fun" must be a string')
end  
if ~isnumeric(x)
   error('Input argument "x" must be numeric')
end  
if ~isnumeric(c)
   error('Input argument "c" must be numeric')
end  
k = nargin - 2;
Z = cell(k,1);
N = nan(k,1);
evalString = 'resi = feval(fun';
for j = 1:k
    switch j
        case 1,    Z{j} = c;
        case 2,    Z{j} = x;
        otherwise, Z{j} = varargin{j-2};
    end        
    evalString = [evalString ',Z' num2str(j) 'boot'];
    if ~isnumeric(Z{j})
       error('Input arguments other than "fun" must be numeric')
    end   
    N(j) = length(Z{j});
end 
evalString = [evalString ');'];
n = unique(N(N > 1));
if ~isscalar(n)
   error('Non-scalar input arguments must have the same number of rows')
end   
u = unique(c);
m = length(u);
M = nan(m,1);
for j = 1:m
    ij   = c == u(j);
    M(j) = sum(ij);
    eval(['ic' num2str(j) ' = find(ij);'])
end
for i = 0:b
    if i == 0
       iboot = (1:n)'; %#ok
    else
       iboot = [];
       for j = 1:m
           nj = M(j);
           ibootj = ceil(nj*rand(nj,1)); %#ok
           ibootj = eval(['ic' num2str(j) '(ibootj);']);
           iboot  = [iboot; ibootj];
       end 
    end
    for j = 1:k
        if N(j) == 1
           eval(['Z' num2str(j) 'boot = Z{j};'])
        else
           eval(['Z' num2str(j) 'boot = Z{j}(iboot,:);']) 
        end 
    end 
    try
       eval(evalString)
    catch
       error('Function "fun" could not be evaluated')  
    end
    if i == 0
       if isstruct(resi) 
          outputStructure = true;
          f = fieldnames(resi);
          r = length(f);
       else
          outputStructure = false; 
          [n1,n2] = size(resi);
          res = nan(n1,n2,n+1);
       end    
    end
    if outputStructure
       for j = 1:r
           eval(['res(i+1).' f{j} ' = resi.' f{j} ';']);
       end
    else
       res(:,:,i+1) = resi;
    end
end

Contact us at files@mathworks.com