2013-03-17 122 views
2

我有有20个字符的变量SAS数据集,所有这些都是名字创建变量(例如亚当,鲍勃,徐子淇等)SAS - 从宏观变量

我想一个动态的代码来创建变量称为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; 

回答

1

如果你想创建一个空数据集,其变量的名字就像你在宏变量中的某些值一样,你可以这样做。

保存的值转换成由一些模式命名的宏观变量,如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; 
1

您可以使用PROC TRANSPOSE与ID声明。

此步骤创建的示例数据集:

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

此步骤基本上是你的步骤的副本上述产生的列名的一个数据集。我将在整个范围内重用数据集namerefs。

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; 
1

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

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

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

这会产生一个空格分隔的宏,可用所需的名称进行变化。

第二步要建立空的数据集,那么这个代码将工作:

Data New ; 
    length &name_list ; 
run ; 

你能避免承担的长度或通过使用一个稍微复杂的SELECT语句创建一个新的变量名填充数据集。

例如

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

将产生保持每个变量的先前长度的宏变量。这将不会对上述步骤2进行更改。

要创建填充的数据与重命名数据集选项设置使用,更换select语句如下:

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

然后用以下替换第2步代码:

Data New ; 
    set names (rename = (&name_list)) ; 
run ;