如何处理大量比较,然后处理总分

时间:2013-07-27 00:30:47

标签: sas

我遇到了一些我正在努力解决的问题,我认为我很接近但不能完成任务。

我有一个数据集,包含16行/ 40个不同人的观察值。我想要计算的是,如果16个观测值中的每一个都获得了2个分数中较高的一个,那么哪一对会产生最高值。

data test; 
input A B C D; 
datalines; 
22.82 17.74 5.94 19
10.16 17.74 23.12 6.62
10.62 10.76 24.72 11.3
28.06 6.92 22.26 11.34
;
run;

以上是一个4x4而不是16x40的片段版本,以便于阅读。

我想出了一个小数据步骤和宏,它通过将2个标签附加在一起来处理比较和新变量的创建。

data test2;
set test;

%macro mk_combinations(first_var, second_var);
    &first_var._&second_var. = max(of &first_var. &second_var.);
%mend mk_combinations;

%mk_combinations(A, B);
%mk_combinations(A, C);
%mk_combinations(A, D);
%mk_combinations(B, C);
%mk_combinations(B, D);
%mk_combinations(C, D);
run;

这实现了我所寻找的显示A和C的组合导致最高总计,但是有40个变量,多次手动调用此宏是不可行的。

为了使事情复杂化,该字段不是单个字符,而是名字和姓氏字段,我也有一个我可以使用的数字ID,但在proc转置后,它会产生_1至_40。

所以我的问题的第一部分是如何以编程方式调用%mk_combinations的最佳方式?我已尝试使用do循环的数组但无法使其工作。

第二个问题,一旦我解决了这个问题,简单地总计16个观察结果的最简单方法是什么?起初我认为这将是容易的部分,但我知道的每个方法都依赖于调用所有变量来明确求和,即proc意味着或proc proc。

有关如何解决此问题的任何想法?有没有更好的方法解决这个问题?

1 个答案:

答案 0 :(得分:1)

在我看来,您需要修改数据结构才能有效地解决问题。我尝试从垂直结构开始,看看你是否可以先解决这个问题。

data have;
array people[40];
do _n_ = 1 to 16;
  do _t_ = 1 to dim(people);
    people[_t_] = 20*ranuni(7);
  end;
  output;
end;
drop _:;
run;

data have_vert;
set have;
array people[40];
do person = 1 to dim(people);
  people_value = people[person];
  obs_value = _n_;
  output;
end;
keep person people_value obs_value;
run;

这样你就有3个变量而不是40个。现在进行分析(我没有足够好地完成它,但它应该很容易)。

如果这更容易,你也可以尝试翻转(人们作为行,观察作为列)。

要回答您遇到的特定问题,两者都使用相同的技巧。

proc sql;
 select name into :namelist separated by ' ' 
  from dictionary.columns
  where libname='WORK' and memname='HAVE' and name ne 'ID';

退出;

这使用SELECT INTO创建一个宏变量(&namelist,:替换创建阶段中的&以便您可以在创建中使用&来指示一些替换文本),其中包含结果选择查询。通过在宏变量中的结果之间放置分隔符(通常是空格,有时是逗号或分号)来分隔。此特定查询使用dictionary.columns,这是包含所有库中所有数据集中所有列的数据集(因此where子句)。

所以,你的第一个问题可以通过使用dictionary.columns的连接来解决,以创建笛卡尔积。你的第二个将以类似的方式完成,创建所有变量的列表,以总结PROC MEANS(或其他)。

最后:考虑阅读一些可能对您正在进行的分析有用的SAS PROC,而不是全部手动完成。我不知道你在一天结束时做了什么,但这让我感到震惊,因为SAS / STAT过程可能会为你做些什么。或SAS / IML。