我是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
的每次观察中?
答案 0 :(得分:4)
有几种方法可以做到这一点;这是一个使用SAS POINT=
选项:
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;
RETAIN
和DROP
语句定义一个临时变量来保存您要添加的值。 RETAIN
表示每次通过数据步骤都不会重新初始化值,DROP
表示您不希望在输出数据集中包含该变量。
POINT=
选项允许用户从SAS数据集中读取特定观察值。 _n_=1
部分是一种控制机制,只执行一次代码,将变量adder
分配给第三次观察的值。
下一部分一次读取一个观察数据集,并添加应用您的更改。
请注意,相同的数据集会被读取两次;一个方便的SAS功能。
答案 1 :(得分: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;
要使用 First 观察来做到这一点,它会更容易。
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和类似的数据库,并没有真正承认任何行是"首先"或"秒"或" nth&#34 ;;但是,与SQL不同,它确实让你假装它是基于当前的排序。 POINT =随机访问方法是实现此目的的一种方式。
但是,大多数情况下,您将使用数据中的某些内容来确定您要执行的操作,而不是与数据排序相关的操作。这里有一种方法可以做与POINT =方法相同的事情,但是使用ID的值:
数据想要; 如果 n = 1则设置为(where =(ID = 3)rename = number = number3); 设有; 数字2 =数+ number3的; 运行;
在数据步骤(_N_
= 1)的第一次迭代中,从HAVE获取行,其中Id = 3,然后从行中获取行(实际上它是这样做的:)
*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会自动保留(yay!),并且不会在数据步循环的迭代之间设置为丢失。只要您不修改该值,它就会保留每次迭代。