我的数据如下:
wait-notify
我想根据data have;
length
group 8
replicate $ 1
day 8
observation 8
;
input (_all_) (:);
datalines;
1 A 1 0
1 A 1 5
1 A 1 3
1 A 1 3
1 A 2 7
1 A 2 2
1 A 2 4
1 A 2 2
1 B 1 1
1 B 1 3
1 B 1 8
1 B 1 0
1 B 2 3
1 B 2 8
1 B 2 1
1 B 2 3
1 C 1 1
1 C 1 5
1 C 1 2
1 C 1 7
1 C 2 2
1 C 2 1
1 C 2 4
1 C 2 1
2 A 1 7
2 A 1 5
2 A 1 3
2 A 1 1
2 A 2 0
2 A 2 5
2 A 2 3
2 A 2 0
2 B 1 0
2 B 1 3
2 B 1 4
2 B 1 8
2 B 2 1
2 B 2 3
2 B 2 4
2 B 2 0
2 C 1 0
2 C 1 4
2 C 1 3
2 C 1 1
2 C 2 2
2 C 2 3
2 C 2 0
2 C 2 1
3 A 1 4
3 A 1 5
3 A 1 6
3 A 1 7
3 A 2 3
3 A 2 1
3 A 2 5
3 A 2 2
3 B 1 2
3 B 1 0
3 B 1 2
3 B 1 3
3 B 2 0
3 B 2 6
3 B 2 3
3 B 2 7
3 C 1 7
3 C 1 5
3 C 1 3
3 C 1 1
3 C 2 0
3 C 2 3
3 C 2 2
3 C 2 1
;
run;
将observation
分成两列。
day
敏锐的SO读者会注意到我提出了基本相同的问题previously。但是,由于SAS对"级别"的痴迷由于用于分割感兴趣的变量的变量不是二进制的,因此该解决方案并不是一般的。
和" by groups"直接尝试,会发生以下情况:
observation_ observation_
Obs group replicate day_1 day_2
1 1 A 0 7
2 1 A 5 2
3 1 A 3 4
4 1 A 3 2
5 1 B 1 3
6 1 B 3 8
7 1 B 8 1
8 1 B 0 3
9 1 C 1 2
10 1 C 5 1
11 1 C 2 4
12 1 C 7 1
13 2 A 7 0
14 2 A 5 5
15 2 A 3 3
16 2 A 1 0
17 2 B 0 1
18 2 B 3 3
19 2 B 4 4
20 2 B 8 0
21 2 C 0 2
22 2 C 4 3
23 2 C 3 0
24 2 C 1 1
25 3 A 4 3
26 3 A 5 1
27 3 A 6 5
28 3 A 7 2
29 3 B 2 0
30 3 B 0 6
31 3 B 2 3
32 3 B 3 7
33 3 C 7 0
34 3 C 5 3
35 3 C 3 2
36 3 C 1 1
错误:ID值" _1"在同一个BY组中出现两次。
我可以使用LET语句来压制错误,但除了使日志混乱之外,SAS仅保留每个BY组的最后一次观察。
proc sort data = have out = sorted;
by
group
replicate
;
run;
proc transpose data = sorted out = test;
by
group
replicate
;
var observation;
id day;
run;
我不怀疑它是否可以采取一些克服方式,例如将每个组拆分为单独的数据集然后重新合并它们。看起来应该可以使用PROC TRANSPOSE,尽管如何让我感到惊讶。有什么想法吗?
答案 0 :(得分:1)
不确定你在谈论" SAS的痴迷......",但这里的问题相当简单;你需要告诉SAS四行(或其他)是独立的,不同的行。 by
告诉SAS行级别ID是什么,但当您说by group replicate
时,您会对其说谎,因为在此之下仍有多行。所以你需要一把独特的钥匙。 (在任何类似数据库的语言中都是如此,这里SAS没有什么独特之处。)
我会这样做 - 制作一个day_row
字段,然后按此排序。
data have_id;
set have;
by group replicate day;
if first.day then day_row = 0;
day_row+1;
run;
proc sort data=have_id;
by group replicate day_row;
run;
proc transpose data=have_id out=want(drop=_name_) prefix=observation_day_;
by group replicate day_row;
var observation;
id day;
run;
答案 1 :(得分:1)
您的输出看起来不想转置数据,而只是想将其拆分为DAY1和DAY2设置并将它们合并在一起。这将按照它们出现的顺序将每个BY组的多个读数配对,这就像您在示例中所做的那样。
data want ;
merge
have(where=(day=1) rename=(observation=day_1))
have(where=(day=2) rename=(observation=day_2))
;
by group replicate;
drop day ;
run;
您可以根据需要为DAY的值数量多次读取源数据。
如果您认为每个DAY的每个BY组可能没有相同数量的观察值,那么您应该在数据步骤结束时添加这些语句。
output;
call missing(of day_:);