【问题标题】:SAS: How do I randomly select rows from my data and copy its variables?SAS:如何从数据中随机选择行并复制其变量?
【发布时间】:2015-07-15 19:22:47
【问题描述】:

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

首先我导入我的数据:

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

提前感谢您的帮助。

【问题讨论】:

  • 我认为你在这里解释得不够充分。但是,我会先看看Don't be LOOPy - 看看这是否能回答你的问题。这假设你正在做一些类似引导分析的事情。如果这不能回答您的问题 - 那么我建议您制作一个“想要”数据集,该数据集具有您想要从运行 DO n=1 to 30 或其他合理的东西中获得的结果。
  • 谢谢@Joe,我试图澄清一下我的问题。感谢您向我指出不要 LOOPy。我不确定它是否能回答我的问题,但我会再看一遍。
  • 那么,你想要像上面这样的 1000 行吗?在这种情况下,您正在使用替换进行采样,而 Don't Be LOOPy 可以向您展示这一点。 (真的,这是一个 n=1000 samplesize=1 的引导程序,或者是一个 n=1 samplesize=1000 的引导程序——不确定是哪个。)

标签: sas


【解决方案1】:

这实际上是一个非常小的引导程序,样本大小为 1000 次重复。如果这正是你想要的,那么,宾果游戏,你在这里,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;

现在,如果您真的想要一个正常的引导分析(样本量大于 1 - 通常它与您的初始样本量相同),您可以调整 sampsize=rep= 数量,直到得到你所期望的。

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

【讨论】:

  • 这是使用sasfile 声明的好机会。
  • 本质中,这是可行的,但是因为这部分适合我正在运行的较大代码,它需要在 DO 中工作我在上面指定的循环。 DO 循环必须指定重复次数,所以就像我需要 PROC SURVEYSELECT 来执行sampsize=1rep=1,但在 DO 循环中重复了 1000 次。但是,如果我尝试使用 sampsize=1rep=1 将 PROC SURVEYSELECT 放入我的 DO 循环中,我的大部分后续代码(主要是 if 语句)都会变成红色。
  • @GavinM.Jones 听起来您需要更多地了解 SAS 的工作原理,尽管很难准确地说出。此过程将初始样本生成为数据集,然后该数据集应作为下一步的输入。你不应该在 procsurveyselect 周围有一个 DO 循环,它会自动为你选择东西。
  • 感谢@Joe 的所有帮助。
【解决方案2】:

您可以使用set 语句中的point= 选项来执行此操作。首先弄清楚数据集中有多少观察值是您想要从中提取数据的。将观察次数保存到名为 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 语句。一旦我们有了它,做你的事情并输出记录。一旦我们迭代了所需的次数,就强制终止数据步:

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 */

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-22
    • 1970-01-01
    • 2021-05-11
    • 1970-01-01
    • 1970-01-01
    • 2014-02-01
    • 2013-06-14
    • 1970-01-01
    相关资源
    最近更新 更多