在SAS中使用retain语句在组中创建相同的值

在SAS中使用retain语句在组中创建相同的值,sas,retain,Sas,Retain,我试图创建一个变量z,它将根据组内第一个观测值的两个变量X和Y的值,在组内取相同的值。根据组中第一次观察的X和Y值,有4个可能的Z值 Z=1 (if X=1 & Y=1), Z=2 (if X=2 & Y=1), Z=3 (if X=1 & Y=2), and Z=4 (if X=2 & Y=2). 这就是我拥有的和我想要的 X has two values, 1 or 2, within a group; while Y can take 1, 2 ,3

我试图创建一个变量z,它将根据组内第一个观测值的两个变量X和Y的值,在组内取相同的值。根据组中第一次观察的X和Y值,有4个可能的Z值

Z=1 (if X=1 & Y=1), 
Z=2 (if X=2 & Y=1),
Z=3 (if X=1 & Y=2), and 
Z=4 (if X=2 & Y=2). 
这就是我拥有的和我想要的

X has two values, 1 or 2, within a group; while Y can take 1, 2 ,3. 
Y is sorted in ascending order 
if the first (or all group observations) take a value of 3, the resulting Z 
value should be set to missing  
这就是我所拥有的:

Obs    Group          X            Y
1      10600          1            1
2      10600          1            2
3      10600          1            3
4      10800          2            1
5      10800          2            3
6      10900          1            2
7      10900          1            3
8      11100          2            2
9      11100          2            2
10     11100          2            3
11     11100          2            2
12     11200          2            3
13     11300          2            1
14     11300          2            2
15     11300          1            3
16     11300          1            3
17     11300          1            3
18     11300          1            3
这就是我想要的:

Obs    Group          X            Y         Z
1      10600          1            1         1
2      10600          1            2         1
3      10600          1            3         1
4      10800          2            1         2
5      10800          2            3         2
6      10900          1            2         3
7      10900          1            3         3
8      11100          2            2         4
9      11100          2            2         4
10     11100          2            3         4
11     11100          2            2         4
12     11200          2            3         .
13     11300          2            1         2
14     11300          2            2         2
15     11300          1            3         .
16     11300          1            3         .
17     11300          1            3         .
18     11300          1            3         .

谢谢大家!

一个
retain
ed变量将携带一个值到数据步骤的前向迭代中,这是正确的。名义上,一个简单的数据步骤和一个
set
语句迭代将对应于数据集中的一行

您保留的变量将在组的开始处赋值,因此您需要一个
by
语句,这反过来会使自动标记变量
首先可用。

data have; input
Group  X Y; datalines;
10600  1 1
10600  1 2
10600  1 3
10800  2 1
10800  2 3
10900  1 2
10900  1 3
11100  2 2
11100  2 2
11100  2 3
11100  2 2
11200  2 3
11300  2 1
11300  2 2
11300  1 3
11300  1 3
11300  1 3
11300  1 3
run;
group=11300
的最后一组行具有
x=2
,后跟
x=1
。你的叙述

群内

传达一个想法,但不明确准确。实际分组(基于显示的需求)似乎是
x
的组合。因此,您将需要一个

by group x notsorted;
声明。
notsorted
将导致数据步骤首先设置
最后设置。
基于值的连续性,而不是值的明确顺序

data want;
  set have;
  by group x nostsorted;
  retain z;
  if first.x then do;  * detect first row in combinations "group/x";
    select;
      when (X=1 & Y=1) Z=1;  * apply logic for retained value;
      when (X=2 & Y=1) Z=2;
      when (X=1 & Y=2) Z=3;
      when (X=2 & Y=2) Z=4;
      otherwise Z=.;
    end;
  end;
  logic_tracker_first_x = first.x;
run;

ods listing; options nocenter;
proc print data=want;
run;
输出窗口显示

                               logic_tracker_
Obs    Group    X    Y    z      first_x

  1    10600    1    1    1           1
  2    10600    1    2    1           0
  3    10600    1    3    1           0
  4    10800    2    1    2           1
  5    10800    2    3    2           0
  6    10900    1    2    3           1
  7    10900    1    3    3           0
  8    11100    2    2    4           1
  9    11100    2    2    4           0
 10    11100    2    3    4           0
 11    11100    2    2    4           0
 12    11200    2    3    .           1
 13    11300    2    1    2           1
 14    11300    2    2    2           0
 15    11300    1    3    .           1
 16    11300    1    3    .           0
 17    11300    1    3    .           0
 18    11300    1    3    .           0

请尝试使用以下解决方案,我使用了更简单的方法,每个组只保留第一个Z变量,然后使用同一数据集进行左连接,以在同一组的其余观察值中保留第一个Z变量-

data test;
input group 5. x 1. y 1.;
if x=1 and y=1 then z=1;
else if x=2 and y=1 then z=2;
else if x=1 and y=2 then z=3;
else if x=2 and y=2 then z=4;
datalines;
1060011
1060012
1060013
1080021
1080023
1090012
1090013
1110022
1110022
1110023
1110022
1120023
1130021
1130022 
1130013
1130013
1130013
1130013
;
run;

data test1;
 set test;
 keep group x z;
run;

proc sort data=test1; by group x; run;

data keep_first;
 set test1;
  by group x;
  if first.group or first.x;
run;

proc sql;
create table final
as
select a.group, a.x, a.y, b.z
from test a
left join keep_first b
on a.group=b.group
and a.x=b.x
order by a.group, a.y, a.x;
quit;

第一步的数据线中没有x和y。是。。有。。1060011“10600 1 1”我没有提到任何空格,所以我的线人也读了5,1,1。啊,现在看吧,老眼睛。为你的回应道歉。除了group、x、y和z之外,我如何维护(或带回)数据集中的其他变量?好的,感谢您使用sql创建一个表和十个左连接的有趣方法。作品非常感谢。谢谢你的回复。我尝试了这段代码,但它在每个组中的第一个之后给出了缺少的值。你能用have data试试看它是否有效吗。它可能需要调整bi。谢谢见编辑,似乎工作。Original在
之后缺少分号,否则
,但应该记录一个
错误22-322:语法错误,应为以下错误之一:…
也许您收到了错误,没有查看日志,正在查看以前提交的数据输出。好的,谢谢,可以了。我认为x组未排序也是需要的。非常感谢你的帮助。