在SAS

时间:2016-05-19 09:38:59

标签: sas random-sample

我有一个数据集,我希望从中获取替换样本。当我使用proc surveyselect时,绘制的样本与原始数据集中的顺序完全相同,并且多个绘制将相互写入。

proc surveyselect data=sashelp.baseball outhits method=urs n=1000 out=mydata;

然而,对我来说重要的是,也可以对出局中的位置进行抽样。在proc surveyselect中是否有选项,或者我最好自己抽样rownumber并输出它,如this paper中所述,p4?

作为一个玩具示例(不是SAS表示法),假设我有一个值列表[a, b, c, d],我重复绘制五次(并保持绘制顺序):

先是a,然后是c,然后是a,然后是b,然后是c。我想要的结果是[a, c, a, b, c],但sas只给出类型

的输出
  • [a,a,b,c,c]outhits
  • [a 2, b 1, c 2, d 0]outall)或
  • [a 2, b 1, c 2](没有其他选项)。

2 个答案:

答案 0 :(得分:1)

所以这是一个只需要BASE SAS的解决方案。例如,需要进行微小的更改以允许包含其他列,例如ID或DATE。我并不认为这是最有效的方法。它严重依赖PROC SQL,这是我的偏好。话虽如此,它应该在相当合理的时间内产生你想要的结果。

生成的SQL代码的长度证明需要单独的sas程序。如果您不想在日志中显示整个%included文件,请忽略/source2选项。

生成样本数据

data mymatrix;
  input c1 c2 c3 c4 c5;
  datalines;
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
26 27 28 29 30
31 32 33 34 35
36 37 38 39 40
;

声明Macro%DrawSample

参数:

lib =找到ds的库   ds =从中抽样的表格   out =要生成的表格   outfile =包含插入字符串的sas程序的路径/名称   n =重复次数

%macro DrawSample(lib, ds, out, outfile, n);

  %local nrows ncols cols;

  proc sql;
    /* get number of rows in source table */
    select count(*)
      into :nrows
      from &lib..&ds;

    /* get variable names */
    select name, count(name)
      into :cols separated by " ",
           :ncols
      from dictionary.columns
     where libname = upcase("&lib")
           and memname = upcase("&ds");

  quit;

  data _null_;
    file "&outfile";
    length query $ 256;
    array column(&ncols) $32;
    put "PROC SQL;";
    put " /* create an empty table with same structure */";
    put "  create table &out as";
    put "    select *";
    put "      from &lib..&ds";
    put "        where 1 = 2;";
    put " ";

    do i = 1 to &n;
      %* Randomize column order;
      do j = 1 to &ncols;
        column(j) = scan("&cols", 1 + floor((&ncols)*rand("uniform")));
      end;
      %* Build the query;
      query = cat("  INSERT INTO &out SELECT ", column(1));
      do j = 2 to &ncols;
        query = catx(", ", query, column(j));
      end;
      rownumber = 1 + floor(&nrows * rand("uniform"));
      query = catx(" ", query, "FROM &lib..&ds(firstobs=", rownumber,
                   "obs=", rownumber, ");");
      put query;
    end;
    put "QUIT;";
  run;

  %include "&outfile" / source2;

%mend;

调用宏

%DrawSample(lib=work, ds=mymatrix, out=matrixSample, outfile=myRandomSample.sas, n=1000);

Etvoilà!

答案 1 :(得分:0)

不确定您到底发生了什么,但可能有用的一点是使用选项OUTALL代替OUTHITS。这将创建与原始大小相同的输出数据集,其中selected列显示记录是否已被采样,numberhits列显示该记录的选择次数。每次选择记录时都不会创建一行。

然后,您可以为样本中的所有记录选择观察编号。