4

我对 SAS 很陌生,我正在尝试找出其他语言中可用的一些基本内容。

我有一张桌子

ID  Number
--  ------
1   2
2   5
3   6
4   1

我想创建一个新变量,在其中将 Number 的一个观察值与其他观察值相加,例如

Number2 = Number + Number[3]

ID  Number  Number2
--  ------  ------
1   2       8
2   5       11
3   6       12
4   1       7

如何获得 Number 的第三次观察值并将其添加到Number新变量中的每个观察值中?

4

2 回答 2

4

做这件事有很多种方法; 这是使用 SASPOINT=选项的一个:

data have;
   input ID  Number;
datalines;
1   2
2   5
3   6
4   1
run;

data want;
   retain adder;
   drop adder;
   if _n_=1 then do;
      adder = 3;
      set have point=adder;
      adder = number;
      end;

   set have;
   number = number + adder;
run;

RETAINandDROP语句定义一个临时变量来保存您要添加的值 。RETAIN意味着每次通过数据步骤都不会重新初始化该值以丢失,并且DROP意味着您不想将该变量包含在输出数据集中。

POINT=选项允许人们从 SAS 数据集中读取特定的观察结果。该_n_=1部分是一种控制机制,只执行该位代码一次,将变量分配给adder第三次观察的值。

下一部分一次读取一个观察数据集并添加应用您的更改。

注意同一个数据集被读取两次;一个方便的 SAS 功能。

于 2013-03-19T21:06:20.520 回答
2

我将首先建议 Base SAS 通常不会以这种方式工作。不是它不能,但通常你可以解决大多数问题而无需指向特定的行。

因此,尽管此答案将解决您的明确问题,但在现实世界中可能没有用处;通常在现实世界中,您将有一个匹配键或除“行号”之外的其他元素来组合,如果您这样做了,那么您可以更有效地做到这一点。您还可能以一种使此操作更方便的方式重新排列您的数据结构。

也就是说,你给出的具体例子是微不足道的:

data have;
input ID  Number;
datalines;
1   2
2   5
3   6
4   1
;;;;
run;

data want;
set have;
_t = 3;
set have(rename=number=number3 keep=number) point=_t ;
number2=number+number3;
run;

如果您有 SAS/IML(SAS 的矩阵语言),它与 R 有点相似,那么无论您执行此操作的可能性以及如何执行此操作,这都是一个非常不同的故事。

proc iml;
 a= {1 2, 2 5, 3 6, 4 1}; *create initial matrix;
 b = a[,2] + a[3,2]; *create a new matrix which is the 2nd column of a added 
                      elementwise to the value in the third row second column;
 c = a||b; *append new matrix to a - could be done in same step of course;
 print b c;
quit;

用第一个观察来做到这一点,要容易得多。

data want;
set have;
retain _firstpoint; *prevents _firstpoint from being set to missing each iteration;
if _n_ = 1 then _firstpoint=number; *on the first iteration (usually first row) set to number's value;
number = number - _firstpoint; *now subtract that from number to get relative value;
run;

我将对此进行详细说明。SAS 在逐个记录级别上工作,其中每个记录都在 DATA 步骤中独立处理。(另一方面,PROC 可能不会以这种方式运行,尽管许多在某种程度上会这样做)。SAS 与 SQl 和类似数据库一样,并不真正承认任何行是“第一”或“第二”或“第 n”;但是,与 SQL 不同的是,它确实允许您根据当前排序假装它是。POINT= 随机访问方法是执行此操作的一种方法。

但是,大多数时候,您将使用数据中的某些内容来确定您想要做什么,而不是与数据排序相关的某些内容。这是一种与 POINT= 方法相同的方法,但使用 ID 的值:

数据需要;如果n = 1 然后设置 have(where=(ID=3) rename=number=number3); 设置有;数字2=数字+数字3;跑;

在数据步骤的第一次迭代中(_N_=1)从 HAVE 中取出 Id=3 的行,然后按顺序从 have 中取出行(真的是这样做的:)

*check to see if _n_=1; it is; so take row id=3;
*take first row (id=1);
*check to see if _n_=1; it is not;
*take second row (id=2);
... continue ... 

SET 语句中的变量会自动保留,因此 NUMBER3 会自动保留(耶!)并且不会在数据步骤循环的迭代之间设置为丢失。只要您不修改该值,它将在每次迭代中保留。

于 2013-03-19T21:13:17.497 回答