SAS:如何从数据中随机选择行并复制其变量?

时间:2015-07-15 19:22:48

标签: sas

还有其他关于使用其他语言随机选择行的线程,而且我的问题涉及如何从每个随机选择的行的列中定义变量。

首先我导入我的数据:

proc import OUT = WORK.ROWS
        DATAFILE = "C:\rows.xlsx"
        DBMS = EXCEL REPLACE; GETNAMES = YES; 
run;
proc print;
run;

其中包含10行,每行包含一对两个变量(var1,var2)在不同的列中。它看起来像这样:

obs var1    var2
1   0.8828  0.2245
2   0.8833  0.3109
3   0.8699  0.1579
4   0.9035  0.2993
5   0.9641  0.3590
6   0.8846  0.2542
7   0.8752  0.1343
8   0.9309  0.1188
9   0.9018  0.1761
10  0.8832  0.1439

然后,在DO循环中,

DO n = 1 TO 1000;       *number of simulations to run;

我想从输入数据文件中随机绘制单行,并从我随机绘制的行中复制两个变量的值(var1和var2)在同一个DO循环中进一步使用。换句话说,对于DO循环的每次迭代,我需要定义一个源自同一行的新的随机变量对。

例如,var1和var2的模拟n = 1到n = 4的随机值可能来自obs(行)2,2,10,4:

Simulation #   
n = 1
    var1 = 0.8846   
    var2 = 0.2542
n = 2
    var1 = 0.8846   
    var2 = 0.2542
n = 3
    var1 = 0.9309   
    var2 = 0.1188
n = 4
    var1 = 0.8832   
    var2 = 0.1439

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

这实际上是一个非常小的引导程序,有1000个样本大小为1的重复样本。如果这正是你想要的,那么,宾果游戏,你可以在这里PROC SURVEYSELECT

data have;
input obs var1    var2;
datalines;
1   0.8828  0.2245
2   0.8833  0.3109
3   0.8699  0.1579
4   0.9035  0.2993
5   0.9641  0.3590
6   0.8846  0.2542
7   0.8752  0.1343
8   0.9309  0.1188
9   0.9018  0.1761
10  0.8832  0.1439
;;;;
run;

proc surveyselect data=have out=want seed=7 outhits
                  method=urs sampsize=1 rep=1000;
run;

现在,如果你真的想要一个正常的自举分析(样本量大于一个 - 通常它与你的初始样本的大小相同),你可以只用sampsize=rep=进行跳汰。数量,直到你得到你期望的。

如需进一步阅读,David Cassell的Don't be LOOPy是有关该主题的经典论文。

答案 1 :(得分:0)

您可以使用point=声明中的set选项执行此操作。首先计算出数据集中要从中提取数据的观察数量。将观察数量保存到名为nobs的宏变量中:

data _null_;
  set sashelp.class nobs=i;
  if _n_ eq 2 then stop;
  call symputx ('nobs',i);
run;

检查我们是否获得了预期值:

%put &=nobs;

指定要循环的次数:

%let loops = 1000;

现在在数据集中,使用set语句启动循环。我们将计算1和表中行数之间的随机数。然后,我们将发出直接指向该行的set语句。一旦我们有了这个,做你的事情并输出记录。一旦我们迭代了所需的次数,强制datastep终止:

data want;
  do cnt=1 to &loops;
    random_obs = floor(rand("Uniform")*100/(100/&nobs))+1; * BETTER CHECK THIS MATH IF YOU NEED TO BE REALLY ACCURATE;
    set sashelp.class(keep=age sex) point=random_obs;
    * DO YOUR THING;
    output;
  end;
  stop;
run;

编辑:我忘了提及有时选择相同的'随机'每次运行时观察。如果您想这样做以帮助测试,您需要将此行添加到数据集的顶部:

call streaminit(123); /* set random number seed */