1

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

我有一个数据集,其中包含 40 个不同人的 16 行/观察值。我想计算的是,如果对 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 SQL。

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

4

1 回答 1

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.columnswhich 是包含所有库中所有数据集中所有列的数据集(因此使用 where 子句)。

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

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

于 2013-07-27T04:16:09.947 回答