2015-01-15 93 views
0

SAS初學者。我想從我的輸入中刪除一個變量列表。該列表本身作爲另一個數據集中的觀察值存在。做了一些Google搜索之後,我發現了關於該主題的優秀論文。使用包含varname列表的宏變量刪除變量

http://www2.sas.com/proceedings/sugi30/028-30.pdf

所以我用下面的代碼,以使在宏變量列表:

/*make a list of variables as a macro variable */ 

data _null_; 

length allvars $1000; 

retain allvars ' '; 

set to_drop end=eof; 

allvars = trim(left(allvars))||' '||left(_name_); 

if eof then call symput('varlist', allvars); 

run; 

我現在面臨着三個問題:)

1當我%PUT &VARLIST,日誌只顯示31個變量,而我的列表實際上是2000多個變量。

2)我不清楚明白:trim(left(allvars)) || ' ' || left(_name_);在做什麼。我知道修剪刪除前導空格,左邊是對齊左邊的字符串,但不能理解完整的語句。

3)然後我嘗試使用下面的代碼,我得到一個警告消息,並且降不發生從我inputds砸:

data inputds2 (drop = &varlist); 
    set inputds; 
    run; 



WARNING: The variable avg_weighted in the DROP, KEEP, or RENAME list has never been referenced. 

NOTE: There were 43662 observations read from the data set WORK.INPUTDS. 

NOTE: The data set WORK.INPUTDS2 has 43662 observations and 3465 variables. 

在現實中我的變量名讀起來像:avg_weighted_minutes_view_3739 avg_weighted_minutes_view_7963 avg_weighted_minutes_view_(XXXX)最後4位數字是隨機的。由於我的標籤包含空格,因此是SAS生成的名稱。

編輯:嘗試使用另一個部分工作的代碼 - 它使一個更大的列表 - 在VARIOIST宏變量中的2000+個變量的2000個變量中有1000個左右。

data _null_; 

set to_drop; 

call symput('varlist',trim(

resolve('&varlist') 

)||' '||trim(_name_)); 

run; 

%put &varlist; 

回答

3

我會按提供的順序回答。

1.)如果您有2,000多個要刪除的變量,則1,000個字符不足以保存變量名稱列表,因此列表將被截斷。你需要在你的空數據的步驟分配更多的空間給allvars變量,就像這樣:

data _null_; 
    length allvars $ 10000; /* You may need even more! */ 
    retain allvars; 
    set to_drop end=eof; 
    allvars = trim(left(allvars)) || ' ' || left(_name_); 
    if eof then call symput('varlist', allvars); 
run; 

你可能會得到你所指出,由於變量名中的一個被切斷時,列表中達到日誌消息長度爲1,000個字符。分配更多空間將會有所幫助。

2.)trim()函數刪除字符串中的尾隨空白。 left()左對齊字符串中的字符值,所以任何前導空白都會推回到後面。 ||是SAS中的字符串連接運算符。因此,聲明全文是這樣做的:

  • 從列表中刪除空格,讓" x y "變得"x y"
  • 在末尾添加一個空格以限定變量名稱,因此"x y"變爲"x y "
  • 將下一個變量名稱添加到字符串中,例如"x y "變成"x y z"。最後一個變量名是左對齊的,這樣變量名之間只有一個空格。

3。)由於數據集to_drop中存在輸入數據集中不存在的變量(如果to_drop已創建爲PROC CONTENTS的輸出或類似輸出,則該變量沒有意義),或者列表已被截斷如我所說。爲了避免這個問題,如果to_drop不輸出PROC內容,可以過濾掉不在像這樣的輸入數據集的變量:

proc sql; 
    create table to_drop2 as 
    select distinct a._name_ 
    from to_drop as a 
    inner join dictionary.columns as b 
    on a._name_ = b.name 
    where b.memname = 'INPUTDS'; 
quit; 

但是,如果問題是該名稱被截斷,分配更多的長度將解決這個問題。


也許更好的方法是使用PROC SQL在一個步驟中完成所有操作。這將確保宏變量varlist的長度達到最大允許長度。

proc sql noprint; 
    select distinct a._name_ 
    into :varlist 
    separated by ' ' 
    from to_drop as a 
    inner join dictionary.columns as b 
    on a._name_ = b.name 
    where b.memname = 'INPUTDS'; 
quit; 

注意,加入上dictionary.columns是不必要的,如果to_drop只包含inputds變量。

+0

感謝您的系統答覆。 to_drop包含一個名爲_TYPE_的變量,它們不在inputd中。但是,創建常用名稱列表的SQL代碼不起作用 - 返回0個觀察值的表。我認爲問題與b.name一樣在輸入變量名稱是實際的變量名稱。 – vagabond 2015-01-15 17:07:20

+0

如果我可以將類型從to_drop中刪除,我可能會在家 – vagabond 2015-01-15 17:07:40

+2

我只記得'dictionary.columns'中的'memname'變量是全部大寫的。所以你需要'b.memname ='INPUTDS''來代替。編輯我的答案。請再次嘗試SQL位,看看它是否適用於您。 – 2015-01-15 17:12:45