Dear SAS user forum,
I came across the coding below that is very useful for my work. However, being a basic SAS user I am stuck with getting it to run on SAS 9.4. It seems like there is an issue in then of PROC IML where the table “random” is created.
I really hope that someone can sort this out for me
Kind regards
Hans
DESCRIPTION
This code performs a multi-sample rarefaction. A dataset should consist of columns of values. Each column represents a sample and each row represents a different taxon (e.g., species). Each value represents a number of specimens representing that species. The number of rows with non-zero values represents sample diversity (taxon richness).
************************************************************************
SAS/IML Code written by Michal Kowalewski (Virginia Tech). This version last updated on March 15, 2010
************************************************************************
* THE CODE BEGINS HERE;
OPTIONS linesize=256 pagesize=5000;
*--ENTER THESE MACROVARIABLES;
%let times=100; * - number of iterations to estimate confidence intervals;
*--RAREFACTION MACROVARIABLES;
%let sam=3; * - number of samples to be included in the analysis;
%let cut=3; * - standardized number of specimens per sample;
**********************************************************************;
*ENTER DATA
Note 1: Replace columns of numbers below with your data.
Note 2: You can simply copy-and-paste from Excel or other file containing your data.
Note 3: Modify in according to number of columns present in your dataset, the Loc1-Loc4 line (e.g., if your dataset is composed by 9 columns you should write: loc.1-loc.9).
Note 4: No missing values are allowed.
Note 5: Zero values are allowed.
Note 6: Only integers are allowed.
After completing all above steps you should be ready to run your data. Click on a running man on the SAS taskbar;
**********************************************************************;
Title1'Multi-sample rarefaction (SAS/IML)';
Title2'written by M. Kowalewski, 12/02/2004';
DATA new;
infile cards;
input loc1-loc4;
cards; * this data step will generate a sas-dataset called 'new';
1 3 17 5
2 4 0 4
5 5 0 143
6 6 0 0
17 7 45 0
42 4 8 12
6 2 32 0
0 9 194 0
32 0 4 0
0 17 1 1
1 0 0 2
;
run;
PROC iml;
USE new;
READ all var _num_ into V;
START weight (X,Y);
k=ncol(X);
do i=1 to k;
s=X[1,i];
z=repeat(i,1,s);
zz=zz||z;
end;
zzz=t(zz);
Y=zzz;
FINISH weight;
START ranvec(in,frac,v_out);
k=nrow(in);
v_index=in;
do i=1 to k;
rand=floor((k-i+1)*ranuni(0) + 1);
v_ran=v_ran||v_index[rand];
v_index=remove(v_index,rand);
end;
temp=t(v_ran[,1:frac]);
v_out=temp;
FINISH ranvec;
START recr(X,frac,out);
Z=t(X);
k=ncol(Z);
run weight(Z,Y);
run ranvec(Y,frac,YY);
do i=1 to k;
a=i#(YY=i);
ab=sum(a)/i;
abun=abun//ab;
end;
*out=abun[loc(abun>0),];
out=abun;
FINISH recr;
START FINAL(X,out);
tot=&sam*&cut; *-total number of specimens that will be resampled;
Z=X; * - original data matrix (columns=samples) (rows=species);
index=t(1:ncol(Z));
do i=1 to ×
run ranvec(index,&sam,sam);
rand=Z[,sam]; *-subset of samples, with number of samples defined by the macrovariable "sam";
do j=1 to ncol(rand);
a=rand[,j];
run recr(a,&cut,random);
b=b||random;
c=b[,+];
end;
b=shape(0,nrow(rand),1);
DivR=ncol(loc(c>0));
outt=DivR||&sam||&cut||tot||i;
output=output//outt;
end;
out=output;
FINISH FINAL;
RUN FINAL(V,out);
create random from out;
append from out;
close random;
QUIT;
run;
data report;
set random;
div=col1;
samples=col2;
sam_n=col3;
tot_n=col4;
iter=col5;
drop col1-col5;
proc print;
proc univariate noprint;
var div;
output out=final1 n=iter mean=diver std=std PCTLPRE=P_ PCTLPTS=2.5 25 75 97.5;
proc print;
run;
quit;
Calling @Rick_SAS
I'm not sure iI understand your reply?
The code assumes that the data are all positive counts. You have zeros in your data, which is why it is giving an error.
You can get rid of the zeros in the data to see that the code works (replace them with 1).
The author of the code would be the best person to advise how to proceed. You can fix the problem by defining the WEIGHT module as follows, but I don't know if that change would preserve the behavior of the program.
START weight (X,Y);
k=ncol(X);
do i=1 to k;
s=X[1,i];
if s>0 then do;
z=repeat(i,1,s);
zz=zz||z;
end;
end;
zzz=t(zz);
Y=zzz;
FINISH weight;
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.