macro
boot2mean x1 x5;
  nulldiff diff_o;
  conlevel cil;
  times B;
  examples;
  storavgs x4.

mconstant B n1 n2 i diff_o D_o cil le_pval ge_pval pval2
mconstant alpha2 L L1 L2 lower upper current answer
mcolumn x1 x2 x3 x4 x5 x6 x7 x8
mcolumn c100 c101 c102 c103 c104 c105 c106 c107 c108 c109
default B=5000 diff_o=0

# compute resample means and sort
if nulldiff = 1 | conlevel = 1 | storavgs = 1
  copy x1 x7;
    omit x1 = '*'.
  copy x5 x8;
    omit x5 = '*'.
  let n1=count(x7)
  let n2=count(x8)
  if ( (n1 < 7) OR (n2 < 7) )
    note
    note   Boot2mean is exiting because the size of one (or both) of
    note   the samples is less than 7.  To ensure that the bootstrap
    note   method used by this macro produces reliable confidence
    note   intervals and p-values, each sample size should be at least
    note   7.  If your sample sizes are too small and one or both of 
    note   your samples do not satisfy the normality requirement of the
    note   two-sample t-test, you can use the Mann-Whitney procedure (also
    note   known as the Wilcoxon rank sum procedure).  To access this
    note   procedure use Stat -> Nonparametrics -> Mann-Whitney off
    note   the Minitab main menu.
    note
    exit
  endif
  do i=1:B 
    sample n1 x7 x2; 
      replace.
    sample n2 x8 x6;
      replace. 
    let x3(i)= mean(x2) - mean(x6) 
  enddo 
  sort x3 x3;
  by x3.
elseif examples = 0
  note
  note   Boot2mean is exiting because no computations were requested.
  note   To request a computation use the nulldiff,
  note   conlevel, or storavgs subcommand.  For a list of
  note   examples, use the following command:
  note    
  note     %boot2mean c1 c2;
  note       examples.
  note
  exit
endif  

# hypothesis tests requested; compute p-values
if nulldiff = 1

  # compute le_pval
  let i = B
  while x3(i) > diff_o
    let i = i - 1
  endwhile 
  let le_pval = (B-i)/B

  # compute ge_pval
  let i = 1
  while x3(i) < diff_o
    let i = i + 1
  endwhile
  let ge_pval = (i-1)/B

  # compute 2-sided pvalue, pval2
  if le_pval < ge_pval
    let pval2 = 2*le_pval
  else
    let pval2 = 2*ge_pval
  endif

  note
  note Boot2mean hypothesis testing results:

 let c100 = " p-value for H0: mu1 - mu2 = "
  copy diff_o c101
  text c101 c102
  let c103 = " versus Ha: mu1 - mu2 < "
  copy diff_o c104
  text c104 c105
  let c106 = " is "
  copy le_pval C107
  text c107 c108;
    significant 4.
  concatenate c100 C102 C103 C105 C106 C108 c109
  write c109;
    text;
  file 'TERMINAL'.
 
 let c100 = " p-value for H0: mu1 - mu2 = "
  copy diff_o c101
  text c101 c102
  let c103 = " versus Ha: mu1 - mu2 > "
  copy diff_o c104
  text c104 c105
  let c106 = " is "
  copy ge_pval C107
  text c107 c108;
    significant 4.
  concatenate c100 C102 C103 C105 C106 C108 c109
  write c109;
    text;
  file 'TERMINAL'.

let c100 = " p-value for H0: mu1 - mu2 = "
  copy diff_o c101
  text c101 c102
  let c103 = " versus Ha: mu1 - mu2 NOT equal to "
  copy diff_o c104
  text c104 c105
  let c106 = " is "
  copy pval2 C107
  text c107 c108;
    significant 4.
  concatenate c100 C102 C103 C105 C106 C108 c109
  write c109;
    text;
  file 'TERMINAL'.
    
endif

# confidence interval requested; compute it.
if conlevel = 1

  # compute lower endpoint of CI
  let alpha2 = (100 - cil)/200
  let L = round(alpha2*B)
  if L/B <= alpha2
    let L1 = L
    let L2 = L + 1
  else
    let L1 = L - 1
    let L2 = L
  endif

  # get indices for jumps in empirical distn. fn.
  # find index of first value less than x3(L2)
  if x3(L1) = x3(L2)
    let current = x3(L1)
    let i = L1 - 1
    while x3(i) = current
      let i = i - 1
    endwhile
    let L1 = i
  endif

  # find largest index of values equal to x3(L2)
  let current = x3(L2)
  let i = L2
  while x3(i) = current
    let i = i + 1
  endwhile
  let L2 = i - 1

  # linearly interpolate lower endpoint of CI
  let lower = (B*alpha2 - L1)/(L2 - L1)*(x3(L2)-x3(L1))+x3(L1)

  # compute upper endpoint of CI using same procedure
  # used for lower endpoint but with different alpha2
  let alpha2 = 1 - alpha2
  let L = round(alpha2*B)
  if L/B <= alpha2
    let L1 = L
    let L2 = L + 1
  else
    let L1 = L - 1
    let L2 = L
  endif

  # get indices for jumps in empirical distn. fn.
  # find index of first value less than x3(L2)
  if x3(L1) = x3(L2)
    let current = x3(L1)
    let i = L1 - 1
    while x3(i) = current
      let i = i - 1
    endwhile
    let L1 = i
  endif

  # find largest index of values equal to x3(L2)
  let current = x3(L2)
  let i = L2
  while x3(i) = current
    let i = i + 1
  endwhile
  let L2 = i - 1

  # linearly interpolate upper endpoint of CI
  let upper = (B*alpha2 - L1)/(L2 - L1)*(x3(L2)-x3(L1))+x3(L1)

  # output result

  let c100 = "Boot2mean "
  copy  cil c101
  text c101 c102
  let c103 = "% confidence interval for mu_1 - mu_2: ( "
  copy lower c101
  text c101 c104;
    significant 4.
  let c105 = ", "
  copy upper c101
  text c101 c106;
    significant 4.
  let c107 = " )"
  concatenate c100 c102 c103 c104 c105 c106 c107 c108
  write c108;
    file 'TERMINAL'.
    
endif

if storavgs = 1
  copy x3 x4
endif

if examples = 1
  note   
  note  Boot2mean examples:
  note
  note  To test a hypothesis concerning the
  note  population mean difference mu_1 - mu_2
  note  using data in c8 and c9 with mu_1 - mu_2 = 2,
  note  use boot2mean with the 'nulldiff'
  note  subcommand as follows:
  note
  note     %boot2mean c1 c2;
  note        nulldiff 2.
  note
  note  Note that the 'nulldiff' subcommand is used
  note  to specify the null value of mu_1 - mu_2.
  note
  note  Continue with a confidence interval example (y/n)?
  yesno answer
  if answer = 0
    exit
  endif
  note  To compute a 95% confidence interval for
  note  mu_1 - mu_2 using data in c8 and c9, call
  note  boot2mean with 'conlevel' subcommand as
  note  follows:
  note  
  note     %boot2mean c8 c9;
  note        conlevel 95.
  note
  note  Note that the 'conlevel' subcommand is used
  note  to specify the confidence level of the CI.
  note
  note  Continue (y/n)?
  yesno answer
  if answer = 0
    exit
  endif
  note
  note  As with any Minitab macro, you can use multiple
  note  subcommands with boot2mean simultaneously, e.g.,
  note
  note     %boot2mean c8 c9;
  note        nulldiff 2;
  note        conlevel 95.
  note
  note  Note that the multiple subcommands are separated
  note  by semicolons with the final subcommand ended by
  note  a period.
  note
  note  Would you like full list of boot2mean subcommands (y/n)?
  yesno answer
  if answer = 0
    exit
  endif
  note
  note  Full syntax for boot2mean:
  note
  note     %boot2mean c1 c2;
  note        nulldiff k1,
  note        conlevel k2,
  note        times k3,
  note        examples,
  note        storavgs c2.
  note
  note   The 'times' subcommand allows you to change the
  note   number of resamples used from 5000 to k3.
  note
  note   The 'storavgs' subcommand allows you to store the
  note   the means from all the resamples (sorted in ascending
  note   order) in the specified column, here c2.
  note
endif

endmacro