SAS создает вложенные таблицы, упорядоченные по годам

#sas

#sas

Вопрос:

У меня есть таблица в SAS, которая состоит из данных с фондовой биржи. Один из его столбцов содержит информацию о дате. Я хотел бы создать вложенные таблицы, каждая из которых содержит данные только за один конкретный год.

Ответ №1:

Предполагая, что вы хотите это сделать (часто это более слабый вариант, поскольку анализы, выполняемые отдельно по годам, могут выполняться из одного набора данных by year; , но, конечно, иногда это может быть уместно), золотым стандартным методом для этого является хеш-таблица, поскольку хеш-таблица может создавать неограниченное количество таблиц на основеданные. Я отредактирую метод для выполнения этого с помощью хэш-таблицы, если у меня будет время во время выполнения задач сегодня днем; это метод «хеширования», описанный на этой странице .

Код хеширования, адаптированный из sascommunity.org страница выше:

 data have;
call streaminit(7);
do year=1998 to 2014;
  do id=  1 to 10;
    x=rand('Uniform');
    output;
  end;
end;
run;


data _null_ ;
  dcl hash byyear   () ;
  byyear.definekey  ('k') ; if `id` or similar is a safe unique ID you could use that here, otherwise `k` is your unique identifier - hash requires unique;
  byyear.definedata ('year','id','x') ;
  byyear.definedone () ;
  do k = 1 by 1 until ( last.year ) ;
    set have;
    by year ;
    byyear.add () ;
  end ;
  dsetname=cats('year',year);
  byyear.output (dataset: dsetname) ;
run ;
  

Существует аналогичный набор методов, которые вращаются вокруг использования макроса для генерации кода. В этой статье подробно рассказывается об одном способе сделать это; Я не буду подробно объяснять это, поскольку считаю, что он уступает методу хеширования (даже если он занимает меньше процессорного времени, его сложнее написать, чем метод чистого макроса или метод чистого хеширования), но в некоторых случаях этомогло бы быть лучше.

Простой пример метода макросов с использованием концептуального have фрейма, определенного:

 proc sql;
  select distinct(cats('year',year(date))) into :dsetlist 
   separated by ' '
   from have;
  select distinct(cats('%outputyear(year=',year(date),')')) into :outputlist
   separated by ' '
   from have;
quit;

%macro outpuyear(year=);
  if year(date)=amp;year. then output yearamp;dset.;
%mend outputyear;

data amp;dsetlist.;
  set have;
   amp;outputlist.;
run;
  

Ответ №2:

 data year1 year2 year3 yearN;
    set stockdata;
    if year(date) = 2014 then
        output year1;
    else if year(date) = 2013 then
        output year2;
    else if year(date) = 2012 then
        output year3;
    else 
        output yearN;
run;
  

Я думаю, вы также могли бы использовать операторы case.