2013-03-17 123 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 ;