我需要创建一个超过300万行的数据集的随机排列。
我试图使用PROC PLAN,基于这个例子:http://support.sas.com/kb/23/977.html根据这篇文章,有n =(行数)!允许随机选择排列。不幸的是,对于这个大小的集合,即4.3 * 10 ^ 19668676排列。显然我在这里遇到了一些内存问题。
我还发现了一个使用PROC IML的示例,但看起来我的公司没有必要的许可证/软件包来使用它。
任何人都可以为我提供一个改变这个数据集的好方法吗?
答案 0 :(得分:2)
听起来你想把这些行放在一个随机的顺序中。如果是这样,最常见的方法是为每一行创建一个随机值,然后按随机值排序:
DATA augmented ;
SET original ;
sortval = RAND('UNIFORM') ;
RUN ;
PROC SORT DATA=augmented OUT=permuted(DROP=sortval) ;
BY sortval ;
RUN ;
如果希望能够在以后精确地再现随机序列,可以使用CALL STREAMINIT(seedval)调用例程。
您也可以使用PROC SQL [未经测试的代码]执行此操作:
PROC SQL ;
CREATE TABLE permuted(DROP=sortval) AS
SELECT a.*, RAND('UNIFORM') AS sortval
FROM original a
ORDER BY sortval
;
QUIT ;
答案 1 :(得分:2)
类似于Ludwig61所说的,我会做以下
DATA augmented ;
SET original ;
call streaminit(12072015)*optional, if you want to set a seed;
sortval1 = RAND('UNIFORM') ;
sortval2 = RAND('UNIFORM') ;
sortval3 = RAND('UNIFORM') ;
RUN ;
PROC SORT DATA=augmented OUT=permuted(DROP=sortval1 sortval2 sortval3) ;
BY sortval1 sortval2 sortval3;
RUN ;
由于您只需使用一个随机数就会遇到冲突,您可以添加更多随机数,直到您知道自己不会获得任何重复值,然后按这些随机数排序。鉴于Rand('Uniform')函数的周期为2 ^ 19937-1,你可以使用3 - 在这种情况下你唯一的敌人是53位之后SAS的截断。
答案 2 :(得分:1)
这将创建数据的随机混洗,并将随机数种子保存为数据中的列和元数据。您可以省略其中一个或两个,但我想让SAS生成种子并让我保存它以便我可以重现样本/随机播放。使用VIEW以便将观察结果直接传送到PROC SORT。
data shuffle / view=shuffle;
obs = _n_;
set sashelp.cars;
if _n_ eq 1 then call streaminit(0);
r = rand('uniform');
retain seed;
if _n_ eq 1 then seed=symgetn('sysrandom');
run;
proc sort data=shuffle out=shuffle01;
by r;
run;
%put NOTE: &=sysrandom;
proc datasets nolist;
modify shuffle01(label="SEED=&sysrandom");
run;
quit;
proc contents;
run;
proc print;
run;