- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I want to generate say 100 data points each having 4 variables, and each variable is a random number between 1 and 10 such that each of the 4 variables is unique for a given data point, i.e, no repetition on the data points level.
Thank you.
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Hi @ilikesas,
This is an opportunity to employ the rarely used CALL RANPERK routine.
data want(drop=_:);
array r[10] v1-v4 _x1-_x6 (1:10);
_seed=27182818;
do _i=1 to 100;
call ranperk(_seed, 4, of r[*]);
output;
end;
run;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Use PROC SURVEYSELECT to randomly select 4, with 100 repetitions and no replacement option per sample.
If required, transpose the output to your desired format.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Here is a data step approach
data want(keep = v:);
array s {10} _temporary_;
array v {4};
do i = 1 to 100;
h = dim(s);
do _N_ = 1 to dim(s);
s[_N_] = _N_;
end;
do j = 1 to dim(v);
r = rand ("integer", h);
v [j] = s[r];
s [r] = s[h];
h = h - 1;
end;
output;
end;
run;
Result:
Obs v1 v2 v3 v4 1 10 4 6 8 2 4 5 10 3 3 1 7 6 8 4 6 9 4 10 5 1 10 9 4 ...
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Hi @ilikesas,
This is an opportunity to employ the rarely used CALL RANPERK routine.
data want(drop=_:);
array r[10] v1-v4 _x1-_x6 (1:10);
_seed=27182818;
do _i=1 to 100;
call ranperk(_seed, 4, of r[*]);
output;
end;
run;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Another data step approach:
data want;
array vars {4} a b c d;
length all $4 y $1;
do i = 1 to 100;
all = "";
do j = 1 to 4;
do until (not(indexc(all,y)));
vars{j} = rand('integer',1,10);
y = put(vars{j} - 1,z1.);
end;
substr(all,j,1) = y;
end;
output;
end;
keep a b c d;
run;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
The simplest syntax is to use the SAMPLE function in SAS/IML:
proc iml;
/* sample 4 items (without replacement) from the items 1:10. Do it 100 times */
X = sample(1:10, {4 100}, "NoReplace");
/* optional: write to SAS data set */
create Want from X[c=('X1':'X4')]; append from X; close;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
I think this one is better .
X = sample(1:10, {4 100}, "WOR");
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
As Reeza said.
data have;
do x=1 to 10;
output;
end;
run;
proc surveyselect data=have out=temp sampsize=4 rep=100 OUTRANDOM ;
run;
proc transpose data=temp out=want;
by Replicate;
var x;
run;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
It's worth mentioning that the result of SURVEYSELECT as implemented by Reeza/KSharp will return rows in sorted order. If it is important that the rows themselves be in a random order, then use RANPERK (DATA step) or SAMPLE (SAS/IML). You can check whether the rows are random by computing the mean of each row:
proc means data=Want;
var col:;
run;
When the rows are in random order, each column has an expected value of 5.5. If the rows are sorted, then the mean of Col1 is less than the mean of Col2, and so forth.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Rick,
Could randomize it before PROC SURVEYSELECT .
%macro x; ods noresult; %do Replicate=1 %to 100; data have; do x=1 to 10; id=rand('uniform'); output; end; run; proc sort data=have;by id;run; proc surveyselect data=have out=temp sampsize=4 ; run; data temp; set temp; Replicate=&Replicate. ; run; proc append base=want data=temp force;run; %end; %mend; proc delete data=want;run; %x proc transpose data=want out=final_want; by Replicate; var x; run; ods result; proc means data=final_Want; var col:; run;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Rick,
You are right . My code is not suited for this question about experiment design .
I think @data_null__ point the right direction by using PROC PLAN .
of course, you iml code is also right . but maybe OP don't have SAS/IML .
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
@Rick_SAS wrote:
It's worth mentioning that the result of SURVEYSELECT as implemented by Reeza/KSharp will return rows in sorted order. If it is important that the rows themselves be in a random order, then use RANPERK (DATA step) or SAMPLE (SAS/IML).
... or add the OUTRANDOM option to the PROC SURVEYSELECT statement.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
It is perfect solution. But need sas version > 9.4M4
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
PROC PLAN of course!
ods exclude all;
proc plan seed=234513;
factors rep=100 ordered rs=4 of 10 random;
ods output plan=plan;
run;
quit;
ods exclude none;
proc print data=plan;
run;