BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Saikiran_Mamidi
Obsidian | Level 7

I am having n observation in a dataset.i want equal observation into 4 datasets?

 

suppose i have 20 obs in a dataset?

i want 1 to 5 obs in one dataset and 6 to 10 in one dataset and 11 to 15 in one dataset and 16 to 20 obs in one dataset?

 

please only code required?

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
ed_sas_member
Meteorite | Level 14

Hi @Saikiran_Mamidi 

 

Here is a code I found and seems to work fine :

%macro split2(num,tab_in);
	data _null_;
		if 0 then set &tab_in nobs=count;
		call symput('numobs', put(count, 8.));
	run;

	%let n=%sysevalf(&numobs/&num, ceil);

	data 
		%do J=1 %to #
			SAMPLE_&J %end;
		;
		set &tab_in;

		%do I=1 %to #
			if %eval(&n*(&i-1)) <_n_ <=%eval(&n*&I) then output SAMPLE_&I;
		%end;
	run;

%mend split2;

/*Sample test*/

data have;
	do i=1 to 15;
		output;
	end;
run;
%split2(4,have);

View solution in original post

4 REPLIES 4
ed_sas_member
Meteorite | Level 14

Hi @Saikiran_Mamidi 

 

Here is a code I found and seems to work fine :

%macro split2(num,tab_in);
	data _null_;
		if 0 then set &tab_in nobs=count;
		call symput('numobs', put(count, 8.));
	run;

	%let n=%sysevalf(&numobs/&num, ceil);

	data 
		%do J=1 %to &num;
			SAMPLE_&J %end;
		;
		set &tab_in;

		%do I=1 %to &num;
			if %eval(&n*(&i-1)) <_n_ <=%eval(&n*&I) then output SAMPLE_&I;
		%end;
	run;

%mend split2;

/*Sample test*/

data have;
	do i=1 to 15;
		output;
	end;
run;
%split2(4,have);
Astounding
PROC Star

You can see that there are simple versions and there are complex (but more flexible) versions.  If you use a macro-based approach, here are a couple of changes to simplify and speed up the program.

 

The macro contains:

 


		%do I=1 %to &num;
			if %eval(&n*(&i-1)) <_n_ <=%eval(&n*&I) then output SAMPLE_&I;
		%end;

This would work equally well:

 



		if _n_ <= &n then output SAMPLE_1;
		%do I=2 %to &num;
			else if _n_ <= %eval(&n*&I) then output SAMPLE_&I;
		%end;
mkeintz
PROC Star

This code will work.

 

data want1 want2 want3 want4;
  set have nobs=nrecs;
  
  select (ceil(_n_/(nrecs/4)));
    when (1) output want1;
    when (2) output want2;
    when (3) output want3;
    otherwise output want4;
  end;
run;

It uses the SET statement option  NOBS=, which stores the number of obs in HAVE in variable nrecs. And it also uses the automatic variable _N_ which is the "iteration" number in the data step - equivalent to the obs number in this program.

 

Now say nrecs=100,  then nrecs/4=25  and _n_/(nrecs/4) ranges from .004, .008,... ,1, 1.004, 1.008, … 4.. And the CEIL functions rounds up to 1,2,3, or 4..

 

Extra observations are written to WANT4, then WANT3, then WANT2.

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
rudfaden
Lapis Lazuli | Level 10

Maybe something like this

 

data have;
do i=1 to 20;
output;
end;
run;

data want1 want2 want3 want4;
set have;
if _N_<=5 then output want1;
else if 5<_N_<=10 then output want2;
else if 10<_N_<=15 then output want3;
else if 15<_N_<=20 then output want4;
run;

Catch up on SAS Innovate 2026

Nearly 200 sessions are now available on demand with the SAS Innovate Digital Pass.

Explore Now →
How to Concatenate Values

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 4 replies
  • 1865 views
  • 2 likes
  • 5 in conversation