⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 metadata.sas

📁 缺失数据的利器
💻 SAS
字号:

%macro metadata(datain= , form=standard, delim='09'x);

  %put Get metadata.;
  %put;

  %let memname = %scan(&datain, 2, .);  /* extract library and member names */
  %if (&memname eq ) %then %do;
    %let libname = WORK;
    %let memname = %upcase(&datain);
  %end;
  %else %do;
    %let libname = %upcase(%scan(&datain, 1, .));
    %let memname = %upcase(&memname);
  %end;

  proc sql;  /* create dataset of libraries and members */
    create view members as
    select libname, memname, memtype
    from dictionary.members;
  quit;

  %let libfound = ;  /* check library and member names */
  %let memfound = ;
  data _null_;
    set members;
    if (libname eq "&libname") then do;
      call symput('libfound', 'y');
      if (memname eq "&memname" and memtype eq "DATA") then call symput('memfound', 'y');
    end;
  run;
  %if (&libfound ne y) %then %let msg = Library &libname not defined.;
  %else %if (&memfound ne y) %then %let msg = Dataset &libname..&memname not found.;
  %else %do;

    %let frames = ;  /* get formats */
    %if (%sysfunc(libref(library)) eq 0) %then %do;
      %if (%sysfunc(exist(library.formats, catalog))) %then %do;
        %let frames = y;
        proc format library=library cntlout=formats;  /* create formats dataset */
        run;
      %end;
    %end;

    %if (&frames eq ) %then %do;  /* no formats */

      proc sql;  /* create variables dataset without formats */
        create view variables as
        select name, type, label
        from dictionary.columns
        where libname = "&libname" and memname = "&memname";
      quit;

      data vars1;  /* change attributes of variables dataset */
        attrib
          Name label="Variable name"
          Type label="Variable type"
          Label label="Variable label"
          ;
        set variables;
      run;

    %end;

    %else %do;  /* formats */

      proc sql;  /* create variables dataset with formats */
        create view variables as
        select name, type, format, label
        from dictionary.columns
        where libname = "&libname" and memname = "&memname";
      quit;

      data vars1;  /* replace formats with codeframes in variables dataset */
        attrib
          Name label="Variable name"
          Type label="Variable type"
          Frame label="Variable codeframe"
          Label label="Variable label"
          ;
        set formats(in=_form_ keep=fmtname) variables end=_end_;
        %if (%sysevalf(&sysver lt 9)) %then %do;
          length form1 - form5000 oldform $ 8;
        %end;
        %else %do;
          length form1 - form5000 oldform $ 32;
        %end;
        retain form1 - form5000 oldform "";
        array formats(5000) form1 - form5000;
        retain _forms_ _frames_ 0;
        keep Name Type Frame Label;
        if (_form_) then do;  /* formats file */
          if (fmtname ne oldform) then do;  /* build formats list */
            oldform = fmtname;
            _i_ = 1;
            do while(_i_ le _forms_);
              if (fmtname eq formats(_i_)) then leave;
              _i_ = _i_ + 1;
            end;
            if (_i_ gt _forms_) then do;
              formats(_i_) = fmtname;
              _forms_ = _i_;
            end;
          end;
        end;
        else do;  /* variables file */
          if (format ne "") then do;  /* drop unmatched formats */
            format1 = upcase(substr(format, 1, 1));
            if (format1 eq '_' or format1 ge 'A' and format1 le 'Z') then do;
              format = substr(format, 1, length(format)-1);
              _i_ = 1;
              do while(_i_ le _forms_);
                if (format eq formats(_i_)) then leave;
                _i_ = _i_ + 1;
              end;
              if (_i_ le _forms_) then do;
                frame = format;
                _frames_ = 1;
              end;
            end;
          end;
          output;  /* write updated variable record */
        end;
        if (_end_ and _frames_ eq 0) then call symput('frames', '');  /* update frames */
      run;

      %if (&frames eq ) %then %do;  /* no referenced codeframes */

        data vars1;  /* drop formats attribute */
          set vars1(drop = frame);
        run;

      %end;

      %else %do;

        data codes1;  /* build codeframes dataset */
          attrib
            Frame label="Codeframe name"
            Value label="Code value"
            Label label="Code label"
            ;
          set vars1(in=_var_ keep=frame) formats(rename=(fmtname=Frame start=Value LABEL=Label)) end=_end_;
          %if (%sysevalf(&sysver lt 9)) %then %do;
            length frame1 - frame5000 oldframe $ 8;
          %end;
          %else %do;
            length frame1 - frame5000 oldframe $ 32;
          %end;
          array frames(5000) frame1 - frame5000;
          retain frame1 - frame5000 oldframe "" _frames_ _keep_ 0;
          keep Frame Value Label;
          if (_var_) then do;  /* variables file */
            if (frame ne "") then do;  /* build frames list */
              _i_ = 1;
              do while(_i_ le _frames_);
                if (frame eq frames(_i_)) then leave;
                _i_ = _i_ + 1;
              end;
              if (_i_ gt _frames_) then do;
                frames(_i_) = frame;
                _frames_ = _i_;
              end;
            end;
          end;
          else do;  /* frames file */
            if (frame ne oldframe) then do;  /* check format */
              oldframe = frame;
              _i_ = 1;
              do while(_i_ le _frames_);
                if (frame eq frames(_i_)) then leave;
                _i_ = _i_ + 1;
              end;
              if (_i_ le _frames_) then _keep_ = 1;
              else _keep_ = 0;
            end;
            if (_keep_) then output;  /* write updated code record */
          end;
        run;

      %end;

    %end;

    %if (%lowcase(&form) eq standard or %lowcase(&form) eq text) %then %do;  /* standard or text output */

      data _null_;  /* write metadata file */
        %if (&frames eq ) %then %do;
          set vars1;
        %end;
        %else %do;
          set vars1(in=_var_) codes1 end=_end_;
        %end;
        %if (&sysver eq 6.12) %then %do;
          length line $ 200 oldframe $ 8;
        %end;
        %else %do;
          length line $ 1024;
          %if (%sysevalf(&sysver lt 9)) %then %do;
            length oldframe $ 8;
          %end;
          %else %do;
            length oldframe $ 32;
          %end;
        %end;
        length oldtype $ 8;
        retain oldtype oldframe ' ' _code_ 0;
        file "&path..met";
        if (_n_ eq 1) then do;  /* write header */
          %if (&form eq standard) %then %do;
            put 'standard;';
          %end;
          %else %if (&delim eq ) %then %do;
            put 'delim " ";';
          %end;
          %else %if (&delim eq '09'x) %then %do;
            put 'delim "\t";';
          %end;
          %else %do;
            put 'delim "' "&delim" '";';
          %end;
          put 'variables';
        end;
        %if (&frames ne ) %then %do;  /* write variable lines */
          if (_var_) then do;
        %end;
            line = 'name=' || name;
            if (label ne ' ') then do;
              line = trim(line) || ' label="';
              do until (label eq ' ');
                next = indexc(label, '"');
                if (next eq 0) then do;
                  line = trim(line) || label;
                  label = ' ';
                end;
                else do;
                  line = trim(line) || substr(label, 1, next) || '"';
                  label = substr(label, next+1);
                end;
              end;
              line = trim(line) || '"';
            end;
            if (type ne oldtype) then do;
              oldtype = type;
              if (type eq 'char') then line = trim(line) || ' type=char';
              %if (&form eq standard) %then %do;
                else line = trim(line) || ' type=float';
              %end;
              %else %do;
                else line = trim(line) || ' type=num';
              %end;
            end;
            %if (&form eq standard) %then %do;
              if (_n_ eq 1) then line = trim(line) || ' width=8';
            %end;
            %if (&frames ne ) %then %do;
              if (frame ne ' ') then line = trim(line) || ' codeframe=' || trim(frame);
            %end;
            line = trim(line) || ';';
            put @3 line;
        %if (&frames ne ) %then %do;  /* write codeframe lines */
          end;
          else do;
            if (frame ne ' ') then do;
              if (frame ne oldframe) then do;
                oldframe = frame;
                if (_code_ eq 0) then do;
                  _code_ = 1;
                  put 'codeframes';
                end;
                else put '    ;';
                put @3 'name=' frame;
              end;
              line = trim(value) || ' = "';
              do until (label eq ' ');
                next = indexc(label, '"');
                if (next eq 0) then do;
                  line = trim(line) || label;
                  label = ' ';
                end;
                else do;
                  line = trim(line) || substr(label, 1, next) || '""';
                  label = substr(label, next+1);
                end;
              end;
              line = trim(line) || '"';
               put @5 line;
            end;
            if (_end_ and _code_) then put '    ;';
          end;
        %end;
      run;

    %end;

  %end;

%mend metadata;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -