【问题标题】:Set the labels of a SAS Dataset equal to their variable name将 SAS 数据集的标签设置为其变量名称
【发布时间】:2015-02-27 16:10:11
【问题描述】:

我正在处理一个相当大的几个数据集,这些数据集以 CSV 文件的形式提供给我。当我尝试导入其中一个文件时,数据会很好,但是文件中的变量数量对于 SAS 来说太大了,因此它停止读取变量名称并开始为它们分配序号。为了维护数据集的变量名称,我在文件中读取的数据行从 1 开始,因此它没有将第一行读取为变量名称 -

proc import file="X:\xxx\xxx\xxx\Extract\Live\Live.xlsx" out=raw_names dbms=xlsx replace;
    SHEET="live";
    GETNAMES=no;
    DATAROW=1;
run;

然后我运行一个宏开始分解数据集并根据每个变量中的第一个观察结果重命名变量 -

%macro raw_sas_datasets(lib,output,start,end);
    data raw_names2;
        raw_names;
            if _n_ ne 1 then delete;
            keep A -- E &start. -- &end.;
    run;
    proc transpose data=raw_names2 out=raw_names2;
        var A -- &end.;
    run;
    data raw_names2;
        set raw_names2;
            col1=compress(col1);
    run;
    data raw_values;
        set raw;
            keep A -- E &start. -- &end.;
    run;
    %macro rename(old,new);
        data raw_values;
            set raw_values;
                rename &old.=&new.;
        run;
    %mend rename;
    data _null_;
        set raw_names2;
            call execute('%rename('||_name_||","||col1||")");
    run;
    %macro freq(var);
        proc freq data=raw_values noprint;
           tables &var. / out=&var.;
        run;
    %mend freq;
     data raw_names3;
        set raw_names2;
            if _n_ < 6 then delete;
     run;
    data _null_;
        set raw_names3;
           call execute('%freq('||col1||")");
    run;
    proc sort data=raw_values;
        by StudySubjectID;
    run;
    data &lib..&output.;
        set raw_values;
    run;
%mend raw_sas_datasets;

我遇到的问题是变量名称现在都设置正确并且数据排列正确,但标签仍然是原始 SAS 分配的序号。有没有办法将所有标签设置为等于变量名?

【问题讨论】:

  • 很可能变量的数量对于 SAS 来说不是太大(我从未认为这是真的),但变量名称的行对于您的 LRECL 来说太长了。我也希望你没有使用 XLSX。
  • 您应该直接导入 CSV,而不是使用 XLSX 作为中介,这会导致您的变量数量出现问题。

标签: sas


【解决方案1】:

在库 sashelp 中是一个表 vcolumn。 vcolumn 按表包含每个库的所有变量名称。您可以编写一个宏,将所有变量名放入宏变量中,然后从那里设置标签。

这是我整理的一些代码(不是很漂亮),但它可以满足您的需求:

data test.label_var;
x=1;
y=1;
label x = 'xx';
label y = 'yy';
run;

proc sql noprint;
     select count(*) into: cnt
            from sashelp.vcolumn
                 where memname = 'LABEL_VAR';quit;
%let cnt = &cnt;

proc sql noprint;
     select name into: name1 - :name&cnt
            from sashelp.vcolumn
                 where memname = 'LABEL_VAR';quit;

%macro test;

   %do i = 1 %to &cnt;

       proc datasets library=test nolist;

            modify label_var;

            label &&name&i=&&name&i;

       quit;

  %end;
%mend test;
%test;

【讨论】:

  • 为什么不把 proc 数据集和退出语句放在宏循环之外呢?如果您使用的是 select into,为什么不直接将标签代码本身选择为单个字符串?
  • 例如select catx(' ','label',name,'="',name,'";') into :labellist separated by ' ' from ...,或者做一个小宏并选择调用它。那你就不用做无用的宏,也不必担心循环...
【解决方案2】:

如果您只想删除变量标签(此时它们默认为变量名称),这很容易。来自SAS Documentation

proc datasets lib=&lib.;
  modify &output.;
  attrib _all_ label=' ';
run;

不过,我怀疑您有比上述更简单的解决方案。

  • 实际的重命名步骤需要以不同的方式进行。现在它一遍又一遍地重写整个数据集——对于很多变量,这是一个糟糕的主意。将您的重命名语句全部放入一个数据步中,或者放入一个 PROC DATASETS 或其他东西中。查找“list processing SAS”以获取有关如何执行此操作的详细信息;在这个网站或谷歌上你会找到很多解决方案。

  • 您可能可以让 SAS 读取整个第一行。变量的数量不是问题;这可能是线的长度。几个月前,如果我可以在这个网站上找到另一个问题,我会找到另一个问题来解决这个确切的问题。

  • 我的首选方案是无论如何都不对 CSV 使用 PROC IMPORT;我建议编写一个元数据表来存储变量名称和变量的长度/类型,然后使用它来编写导入代码。一开始需要做更多的工作,但每次研究只需完成一次,您保证 PROC IMPORT 不会为您做出愚蠢的决定。

【讨论】:

    猜你喜欢
    • 2016-02-05
    • 1970-01-01
    • 2021-06-21
    • 2021-03-23
    • 1970-01-01
    • 2020-02-20
    • 2015-06-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多