在 SAS 中创建子集 "automatically"
CREATING SUBSETS IN SAS "automatically"
我已经通过 sas 生成了一个包含 144 行的数据集,现在我想创建该数据集的 18 个子集(每个子集包含 8 行)。我知道如何 "manually using the firstobs=
and obs=
commands. However, I want the subsets to be created " 自动创建子集。原因是我从特定网站提取数据,每次我 运行 数据集大小不同的代码,我所知道的是每次生成数据集时,我都想创建包含 8 行的 X 个子集(例如,第一个子集将包含第 1-8 行,第二个子集将包含第 9-16 行,依此类推...)。
所以我的问题是,我该如何着手解决这个问题?
宏观方法:
我只是提供了一个粗略的代码。根据您的要求对其进行优化。
proc sql;
select count(*) into :total from source_data;
quit;
%macro create_subsets(count,ds);
%let cnt=%sysfunc(ceil(%sysevalf(&count/8)));
%let num=1;
%do i=1 %to &cnt;
%if(&i = &cnt) %then %do;
%let toread=&count;
%end;
%else %do;
%let toread=&num+7;
%end;
data &ds._&i;
set &ds(firstobs=&num obs=%eval(&toread));
run;
%let num=%eval(&num + 8);
%end;
%mend create_subsets;
%create_subsets(&total,source_data)
根据罗伯特的宝贵意见进行编辑。
注意:非宏观方法总是更容易和更有效。
我不知道你的子集的用途是什么,但将数据集拆分成多个版本通常不是一个好主意。更好的方法是在原始数据集中创建一个变量来保存子集编号,这样以后就可以很容易地提取特定的子集或按它们分组。
这是一个简单的方法,如果记录数不能被 8 整除,最终的子集显然不会有 8 行。我从你的问题中假设 8 行是一个固定数量,而不管记录大小。
data want;
set sashelp.citimon;
subset = ceil(_n_/8);
run;
我已经通过 sas 生成了一个包含 144 行的数据集,现在我想创建该数据集的 18 个子集(每个子集包含 8 行)。我知道如何 "manually using the firstobs=
and obs=
commands. However, I want the subsets to be created " 自动创建子集。原因是我从特定网站提取数据,每次我 运行 数据集大小不同的代码,我所知道的是每次生成数据集时,我都想创建包含 8 行的 X 个子集(例如,第一个子集将包含第 1-8 行,第二个子集将包含第 9-16 行,依此类推...)。
所以我的问题是,我该如何着手解决这个问题?
宏观方法:
我只是提供了一个粗略的代码。根据您的要求对其进行优化。
proc sql;
select count(*) into :total from source_data;
quit;
%macro create_subsets(count,ds);
%let cnt=%sysfunc(ceil(%sysevalf(&count/8)));
%let num=1;
%do i=1 %to &cnt;
%if(&i = &cnt) %then %do;
%let toread=&count;
%end;
%else %do;
%let toread=&num+7;
%end;
data &ds._&i;
set &ds(firstobs=&num obs=%eval(&toread));
run;
%let num=%eval(&num + 8);
%end;
%mend create_subsets;
%create_subsets(&total,source_data)
根据罗伯特的宝贵意见进行编辑。 注意:非宏观方法总是更容易和更有效。
我不知道你的子集的用途是什么,但将数据集拆分成多个版本通常不是一个好主意。更好的方法是在原始数据集中创建一个变量来保存子集编号,这样以后就可以很容易地提取特定的子集或按它们分组。
这是一个简单的方法,如果记录数不能被 8 整除,最终的子集显然不会有 8 行。我从你的问题中假设 8 行是一个固定数量,而不管记录大小。
data want;
set sashelp.citimon;
subset = ceil(_n_/8);
run;