如何在SAS中使用id变量的多个观测值来转换数据?
当我的id变量多次出现时,我想知道在SAS中转置数据的最佳方法。我知道我可以在proc transpose语句中使用let选项来实现这一点,但我不想删除任何数据,因为我打算计算平均值 以下是我的数据和代码示例:如何在SAS中使用id变量的多个观测值来转换数据?,sas,transpose,Sas,Transpose,当我的id变量多次出现时,我想知道在SAS中转置数据的最佳方法。我知道我可以在proc transpose语句中使用let选项来实现这一点,但我不想删除任何数据,因为我打算计算平均值 以下是我的数据和代码示例: data grades; input student testnum grade; cards; 1 1 30 1 1 25 1 2 45 1 3 67 2 1 22 2 2 63 2 2 12 2 2 77 3 1
data grades;
input student testnum grade;
cards;
1 1 30
1 1 25
1 2 45
1 3 67
2 1 22
2 2 63
2 2 12
2 2 77
3 1 22
3 1 17
3 2 14
3 4 17
;
run;
proc sort data=grades;
by student testnum;
run;
proc transpose data=grades out=trgrades;
by student;
id testnum;
var grade;
run;
以下是我希望生成的数据集的外观:
student testnum1 testnum2 testnum3 testnum4 avg12 avg34
1 30 45 67 . 33.33 67
1 25 . . . 33.33 67
2 22 63 . . 43.5 .
2 . 12 . . 43.5 .
2 . 77 . . 43.5 .
3 22 14 . 17 53 17
3 17 . . . 53 17
我想使用这个新的数据集(不确定如何创建)来创建新的列,这些列是一个学生的所有testnum1和testnum2的平均分数(avg12)和一个学生的所有TestNum3和testnum4的平均分数(avg34)
也许有一种更有效的方法可以做到这一点,但我被难倒了。
任何建议都非常感谢。如果您真正需要的是每个学生的所有测试1和2的平均值,以及测试3和4的平均值,那么您根本不需要转换。您只需执行一个简单的数据步骤:
data grouped;
set grades;
if testnum In (1,2) then group=1;
else if testnum in (3,4) then group=2;
run;
然后一个基本的过程意味着
:
proc means data=grouped;
by student group;
var grade;
output out=averages mean=groupaverage;
run;
如果您需要单个观测值中的平均值,您可以轻松地将平均值
数据集转置
proc transpose data=grades out=trgrades;
by student;
id group;
var grade;
run;
更新: 正如@Keith所提到的,使用一种格式对测试进行分组也是一个很好的选择。跳过数据步骤,创建如下格式:
proc format;
value TestGroup
1,2 = 'Tests 1 and 2'
3,4 = 'Tests 3 and 4'
;
run;
然后,proc意味着
变成:
proc means data=grouped;
by student testnum;
var grade;
format testnum TestGroup.;
output out=averages mean=groupaverage;
run;
结束更新
如果出于某种原因,您真的需要在一次观察中获得所有测试分数,那么我建议使用数据步骤使它们唯一可识别。使用
by
,testnum.first
,retain
,以及一个简单的计数器,为每个分数分配一个重做的编号。现在,转置使用retake
和testnum
作为id
变量。你应该能从那里找到答案
我现在真的希望我不是为你做SAS作业。如果你真正需要的是每个学生的所有测试1和2,以及3和4的平均值,那么你根本不需要转换。您只需执行一个简单的数据步骤:
data grouped;
set grades;
if testnum In (1,2) then group=1;
else if testnum in (3,4) then group=2;
run;
然后一个基本的过程意味着
:
proc means data=grouped;
by student group;
var grade;
output out=averages mean=groupaverage;
run;
如果您需要单个观测值中的平均值,您可以轻松地将平均值
数据集转置
proc transpose data=grades out=trgrades;
by student;
id group;
var grade;
run;
更新:
正如@Keith所提到的,使用一种格式对测试进行分组也是一个很好的选择。跳过数据步骤,创建如下格式:
proc format;
value TestGroup
1,2 = 'Tests 1 and 2'
3,4 = 'Tests 3 and 4'
;
run;
然后,proc意味着
变成:
proc means data=grouped;
by student testnum;
var grade;
format testnum TestGroup.;
output out=averages mean=groupaverage;
run;
结束更新
如果出于某种原因,您真的需要在一次观察中获得所有测试分数,那么我建议使用数据步骤使它们唯一可识别。使用by
,testnum.first
,retain
,以及一个简单的计数器,为每个分数分配一个重做的编号。现在,转置使用retake
和testnum
作为id
变量。你应该能从那里找到答案
我现在真的希望我不仅仅是为你做SAS作业。你可以创建一个testnum分组格式,这样就不需要创建额外的变量。Proc意味着将按格式化值分组。非常好,@Keith。我会把这个选项添加到我的答案中。谢谢,这正是我想做的。我原本打算只取最后一个。student,如果我能让我的数据如上面示例中所示,那么每个学生只剩下一行,其中一列为avg12,另一列为avg34,但这非常有效。这不是一个家庭作业问题,所以不用担心。您可以创建一个格式来分组testnum,这样就不需要创建额外的变量。Proc意味着将按格式化值分组。非常好,@Keith。我会把这个选项添加到我的答案中。谢谢,这正是我想做的。我原本打算只取最后一个。student,如果我能让我的数据如上面示例中所示,那么每个学生只剩下一行,其中一列为avg12,另一列为avg34,但这非常有效。这不是家庭作业问题,所以不用担心。