DATA SPP; /* read species name and absence */presence or abundance data. Program is currently

setup for four replicates in each group; if different, change A4 and B4 in the next three lines to indicate the number of replicates in each group. */

INPUT SPNAME $ A1-A4 B1-B4; /* read data for one species */

ARRAY ALLA A1-A4; /* ALLA stores replicates from one group */

ARRAY ALLB B1-B4; /* ALLB stores replicates from the other group */

IJACK = 0; /* IJACK = 0 => full data set */

A = SUM(OF ALLA{*}); /* A = 0 if species absent in group 1 */

B = SUM(OF ALLB{*}); /* B = 0 if species absent in group 2 */

C01 = (A = 0)*(B > 0); /* calculate the bits of the Jaccard coefficient; C01 = in 2 only, C10 = in 1 only, C11 = in both */

C10 = (A > 0)*(B = 0);

C11 = (A > 0)*(B > 0);

OUTPUT; /* store on data set */

DO OVER ALLA; GROUP = 1; /* then jacknife the first group of replicates */

IJACK = IJACK + 1; /* these are numbered IJACK = 1 to NA */

JA = A - ALLA; /* remove data from the ith sample */

C01 = (JA = 0)*(B > 0); /* recalculate bits of the jaccard */

C10 = (JA > 0)*(B = 0);

C11 = (JA > 0)*(B > 0);

OUTPUT; /* store on data set */

END;

NA = IJACK; /* NA = number of samples in 1st group */

DO OVER ALLB; GROUP = 2; /* then jacknife the second group of replicates */

IJACK = IJACK + 1; /* these are numbered IJACK = NA+1 to NA+NB */

JB = B - ALLB; /* remove data from the ith sample */

C01 = (A = 0)*(JB > 0); /* recalculate bits of the jaccard */

C10 = (A > 0)*(JB = 0);

C11 = (A > 0)*(JB > 0);

OUTPUT; /* store on data set */

END;

NB = IJACK - NA; /* NB = number of samples in 2nd group */

CALL SYMPUT("NA",NA); /* store NA and NB in macro variables */

CALL SYMPUT("NB",NB);

/*** USER enters data here. Format is: species name, list of abundances. First NA abundances are for the first group of samples, rest (NB) of abundances are for the second group. Each species goes on one line of data, but you can modify the input command to read other forms of data. ***/

CARDS;

alon3 0 0 0 0 0 0 0 1

.....

;

PROC SORT; BY IJACK; /* compute jaccard coefficient by sorting data by jackknife number */

PROC MEANS SUM NOPRINT; /* then adding up (over species) separately for each jackknife number */

BY IJACK;

VAR C01 -- C11; /* bits of the jaccard coefficient */

ID GROUP; /* include group number */

OUTPUT OUT=SUMS SUM=B C A; /* store on a data set */

DATA JACCARD; SET SUMS; /* use these sums to calculate Jaccard for each jackknife sample */

RETAIN SAMPLE; /* remember J from original sample (needed to calculate pseudo-values */

J = A /(A+B+C); /* Jaccard coefficient formula */

IF IJACK = 0 THEN DO;

SAMPLE = J; /* remember J if this was the original */

CALL SYMPUT("SAMPLE",J); /* also store in a macro variable */

END;

ELSE DO; /* otherwise, compute a pseudovalue */

IF GROUP = 1 THEN */find N for this group */

N = SYMGET("NA");

ELSE N = SYMGET("NB");

PJ = (N-0.5)*SAMPLE - (N-1)*J; /* and compute pseudovalue using Smith et al. (1986) formula */

END;

PROC PRINT; ID IJACK; /* print out the values and pseudovalues */

VAR GROUP A B C J PJ;

TITLE 'JACKNIFE SAMPLES

AND PSEUDOVALUES';

PROC MEANS MEAN STD VAR; /* calculate the within group variances */

WHERE GROUP NE .;

BY GROUP; VAR PJ;

OUTPUT OUT=SD STDERR=SE; /* store standard errors in a data set */

TITLE 'VARIANCES OF

PSUEDOVALUES FOR EACH GROUP';

DATA POOLED; /* calculate standard error of the Jaccard */

SET SD END=LAST; /* LAST is set to 1 on the last obervations */

RETAIN POOL 0; /* POOL stores the sum of variance */N */

POOL = POOL + SE*SE; /* calculated by squaring the standard error */

IF LAST THEN DO;

POOL = SQRT(POOL); /* calculate standard error of the Jaccard */

OUTPUT;

END;

PROC PRINT; /* print results */

TITLE "JACKKNIFE SE FOR JACCARD

COEFFICIENT (SAMPLE J = &SAMPLE)";

VAR POOL;