Применить программу SAS к нескольким наборам данных с помощью макроса - PullRequest
0 голосов
/ 31 марта 2020

Я очень новичок в SAS, поэтому заранее прошу прощения. Я использую университетское издание SAS.

У меня есть 20 наборов данных каждого определенного года (1997-2017), каждый из которых содержит информацию, собранную в 30 переменных. Теперь я хочу применить один и тот же код ко всем наборам данных, однако некоторые фрагменты кода применяются только к переменным определенных лет. Поэтому я хотел использовать макрос, который варьируется от 1997-2017 и выполняет что-то вроде ...

LIBNAME IN '/folders/myfolders/fake_data';

%let j= 1997 to 2017; 

    data fake_&j;
     set fake_data;

proc import out= fake_&j datafile = "/folders/myfolders/fake_data/mz_&j.dta" replace

* Year;
year = j;

, чтобы получить доступ к набору данных fake_1997.dta, создать переменную year, которая принимает значение имени набора данных (1997) примените к нему код (см. Ниже), затем сделайте то же самое с mz_1998.dta и так далее.

Пример кода, который я хочу применить ко всем данным:

* Weights;
    if (j GE 1997 AND j LE 2004) then 
      shrf = x; 
    else if (j GE 2005 AND j LE 2017) then
      shrf = y;

Заранее большое спасибо!

Ответы [ 2 ]

0 голосов
/ 01 апреля 2020

Подход, который не предполагает вложения макросов, - это магические data null и call execute. Я использую это все время. Это наиболее полезно, если наборы данных уже находятся в формате SAS.

libname HAVELIB "path-to-sas-datasets";

data _null_;
  set sashelp.vtable(where=(libname="HAVELIB"));
  call execute("%mymacro(HAVELIB." || strip(memname) || ");");
run;

Создание al oop, который импортирует набор файлов .dta в виде sas7bdat, также просто, создать набор данных на основе выведите infile pipedir и сделайте аналог l oop, используя call execute.

Подробнее здесь:

https://www.lexjansen.com/phuse/2014/cc/CC06.pdf

0 голосов
/ 31 марта 2020

Макрос-код, частично, является кодом, который пишет код. Запись - это не столько активный процесс, как «запись» или «печать» или «эхо», но скорее родственный шаблону или системе шаблонов.

Макрос %DO l oop не может существует в «открытом коде», поэтому он должен быть закодирован внутри определения макроса. Макрос вызывается для того, чтобы он написал (или сгенерировал) код. Иногда вы можете увидеть термин «gencode» для обозначения сгенерированного кода, созданного путем вызова макроса.

Proc IMPORT отлично подходит для регулярного чтения данных или для работы с первыми исследованиями. IMPORT не выполняет никаких преобразований данных и не позволяет добавлять новые переменные во время импорта. Для выполнения этих действий вам потребуется второй шаг - шаг DATA.

Назовите свои макросы в соответствии с их назначением. Любые макропеременные, используемые внутри макроса, должны быть объявлены как %LOCAL для предотвращения нежелательного взаимодействия с глобальными макропеременными.

Пример:

%macro getData(fromYear=, toYear=);

  %local year;

  %DO year = &fromYear %to &toYear;

    * step 1;
    * get initial data set from raw data file;
    * double dot needed because &<NAME>. is a token specifying macro variable resolution;

    proc import 
      datafile = "/folders/myfolders/fake_data/mz_&YEAR..dta" /* double dot */
      replace
      out= import_fake_&YEAR.
    ;

    * step 2;

    data fake_&YEAR;
      set import_fake_&YEAR.;
      year = &YEAR;

      %* macro %if codegens a data step statement specific to year;

      %if &YEAR GE 1997 AND &YEAR LE 2004 %then %do;
        /* anything that is not consumed by macro processing is emitted as a codegen */
        /* so here the macro is emitting a data step assignment statement */
        shrf = x;   
      %end; 
      %else
      %if &YEAR GE 2005 AND &YEAR LE 2017 %then %o
        shrf = y;
      %end;
      %else %do;
        shrf = 1; * uniform weighting ;
      %end;
    run;
  %END;
%mend;

%* invoke;
%getData(fromYear=1997, toYear=2017);

%* this point your might want to combine (stack) all the data sets together
%* so that other Procs can use the 'all' data and utilize CLASS, BY and WHERE
%* statements that are so effective in SAS;

data fake_duodecade;
  set fake_1997-fake2017;  %* special data set name list construct;
run;

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

...