3

我有一个 SAS 数据集,它有 20 个字符变量,所有这些都是名称(例如 Adam、Bob、Cathy 等)

我想要一个动态代码来创建名为 Adam_ref、Bob_ref 等的变量。即使存在具有不同名称的不同数据集(即不想手动定义每个变量),它也可以工作。

到目前为止,我的方法是使用 proc 内容来获取所有变量名称,然后使用宏来创建宏变量 Adam_ref、Bob_ref 等。

如何从这里在数据集中创建实际变量?我需要不同的方法吗?

proc contents data=work.names 
               out=contents noprint;
run;

proc sort data = contents; by varnum; run;

data contents1;
  set contents;
  Name_Ref = compress(Name||"_Ref");
  call symput (NAME, NAME_Ref); 
  %put _user_;
run;
4

3 回答 3

2

如果您想创建一个空数据集,其中的变量名称类似于宏变量中的某些值,您可以执行以下操作。

将值保存到以某种模式命名的宏变量中,例如v1v2...

proc sql;
select compress(Name||"_Ref") into :v1-:v20 from contents;
quit;

如果你不知道有多少个值,你必须先计算它们,我假设它们只有 20 个。

然后,如果您的所有变量都是长度为 100 的字符变量,您将创建一个如下所示的数据集:

%macro create_dataset;
data want;
length %do i=1 %to 20; &&v&i $100 %end;
;
stop;
run;
%mend;

%create_dataset; run; 

如果您在宏变量中有值,这就是您可以做到的方式,通常可能有更好的方法来做到这一点。

如果您不想创建空数据集而只想更改变量名称,则可以这样做:

proc sql;
select name into :v1-:v20 from contents;
quit;

%macro rename_dataset;
data new_names;
set have(rename=(%do i=1 %to 20; &&v&i = &&v&i.._ref %end;));
run;
%mend;

%rename_dataset; run;
于 2013-03-17T17:40:30.957 回答
2

您可以将 PROC TRANSPOSE 与 ID 语句一起使用。

此步骤创建一个示例数据集:

data names;
    harry="sally";
    dick="gordon";
    joe="schmoe";
run;

此步骤本质上是您上述步骤的副本,它会生成列名数据集。我将在整个过程中重用数据集名称引用。

proc contents data=names out=namerefs noprint;
run;

此步骤将“_Refs”添加到之前定义的名称并删除其他所有内容。变量“name”来自 PROC CONTENTS 输出的数据集的列属性。

data namerefs;
    set namerefs (keep=name);
    name=compress(name||"_Ref");
run;

此步骤会生成一个包含所需列的空数据集。通过查看列属性再次获得变量“名称”。如果您尝试查看数据集,您可能会在 GUI 中收到无害的警告,但您可以根据需要使用它,并且可以确认它具有所需的输出。

proc transpose out=namerefs(drop=_name_) data=namerefs;
  id name;
run;
于 2013-03-18T02:17:37.943 回答
1

这是另一种需要较少编码的方法。它不需要运行 proc 内容,不需要知道变量的数量,也不需要创建宏函数。它也可以扩展来做一些额外的事情。

第 1 步是使用内置的字典视图来获取所需的变量名称。合适的视图是 dictionary.columns,它的别名是 sashelp.vcolumn。字典 libref 只能在 proc sql 中使用,而 sashelp 别名可以在任何地方使用。我倾向于使用 sashelp 别名,因为我使用 DMS 在 Windows 中工作,并且始终可以交互地查看 sashelp 库。

proc sql;
  select compress(Name||"_Ref") into :name_list
                                separated by ' '
    from sashelp.vcolumn
   where libname = 'WORK' 
     and memname = 'NAMES';
quit;

这将生成一个带有所需名称的空格分隔宏。

第 2 步要构建空数据集,则此代码将起作用:

Data New ;
  length &name_list ;
run ;

您可以使用稍微复杂一点的 select 语句来避免假设长度或创建具有新变量名称的填充数据集。

例如

 select compress(Name)||"_Ref $")||compress(put(length,best.)) 
                 into :name_list
                 separated by ' '

将生成一个宏变量,该变量保留每个变量的先前长度。这将在不更改上述步骤 2 的情况下工作。

To create populated data set for use with rename dataset option, replace the select statement as follows:

 select compress(Name)||"= "||compress(_Ref") 
                   into :name_list
                   separated by ' '

Then replace the Step 2 code with the following:

Data New ;
  set names (rename = ( &name_list)) ;
run ;
于 2013-09-06T16:42:19.367 回答