2016-08-12 112 views
2

我有一个宏变量&myfiles其中包含四个数据集的名称列表。基于宏变量值复制/重命名多个sas数据集

%put &myfiles; 
cpo.CDR_2016jun cpo.Cog_2016jun cpo.Mile_2016jun cpo.Path_2016jun 

其中cpo是一个libname。

我想从我将其命名&New_Datasets另一个宏变量创建名称四个新的数据集:

%put &New_Datasets; 
CDR Cog Mile Path 

我试图只使用一个数据的步骤是这样的:

data &New_Datasets; 
    set &myfiles; 
run; 

,但是导致将&mylist中引用的四个数据集的所有观察结果合并并放入&New_Datasets中引用的四个数据集的每一个中,其中来自日志的以下输出:

NOTE: There were 1482 observations read from the data set CPO.CDR_2016JUN. 
NOTE: There were 1444 observations read from the data set CPO.COG_2016JUN. 
NOTE: There were 255 observations read from the data set CPO.MILE_2016JUN. 
NOTE: There were 7 observations read from the data set CPO.PATH_2016JUN. 
NOTE: The data set WORK.CDR has 3188 observations and 1580 variables. 
NOTE: The data set WORK.COG has 3188 observations and 1580 variables. 
NOTE: The data set WORK.MILE has 3188 observations and 1580 variables. 
NOTE: The data set WORK.PATH has 3188 observations and 1580 variables. 

我想做到的是有1482个观察从cpo.cdr_2016jun创建一个数据集work.cdr与1482周的观察等,而不是每一个新的数据集是在引用的那些组合设置声明。任何帮助将不胜感激,谢谢!

+1

如果你没有宏变量你会用什么SAS代码来创建你想要的数据集?一旦你知道你想要生成的代码,那么使用宏逻辑来生成它就更容易了。 – Tom

回答

2

您必须编写一个宏程序,循环访问宏变量中的值并调用数据步骤或proc副本。

宏:

%macro rewriteDataSets(source_tables=, dest_tables=); 
    %local ii num_source_tables num_dest_tables source_name dest_name; 

    %let num_source_tables = %sysfunc(countw(&source_tables, %str())); 
    %let num_dest_tables = %sysfunc(countw(&dest_tables , %str())); 

    %if &num_source_tables ne &num_dest_tables %then %do; 
     %put ERROR: The number of source and destination tables must be the same in the call to rewriteDataSets; 
     %abort cancel; 
    %end; 

    %do ii=1 %to &num_source_tables; 

     %let source_name = %scan(&source_tables, &ii, %str()); 
     %let dest_name = %scan(&dest_tables , &ii, %str()); 

     data &dest_name; 
     set &source_name; 
     run; 

    %end; 
%mend rewriteDataSets; 

实例应用:

%rewriteDataSets(source_tables = sashelp.class sashelp.class, 
       dest_tables = a b); 

或者使用您指定的表,你会这样称呼它:

%rewriteDataSets(source_tables = cpo.CDR_2016jun cpo.Cog_2016jun cpo.Mile_2016jun cpo.Path_2016jun, 
       dest_tables = CDR Cog Mile Path); 

或者使用proc copy而不是数据步骤。

+0

这适用于在宏%revriteDatasets&myfiles和&New_Datasets应该切换的小编辑。谢谢! –

+0

我一般喜欢这个,但是你不应该使用全局宏变量。将'&myfiles'和'&new_datasets'作为参数传递。 – Joe

+0

我已经更新了一些代码,以便更容易地看到它是如何工作的(对于那些经验较少的宏),我也添加了一些基本的错误检查。 –

3

我会略有不同的定义我的宏变量,做这样的事情:

%let oldnames = CDR_2016jun Cog_2016jun Mile_2016jun Path_2016jun; 
%let newnames = CDR Cog Mile Path; 

proc datasets lib = cpo noprint; 
    copy out = work; 
    select &oldnames; 
    run; 
quit; 

%macro changes; 
%local i; 
%do i = 1 %to %sysfunc(countw(&oldnames)); 
    %scan(&oldnames, &i, %str()) = %scan(&newnames, &i, %str()) 
%end; 
%mend changes; 

proc datasets lib = work noprint; 
    change %changes; 
    run; 
quit; 

或者,您可以在cpo建立在原有的数据集work意见。

+0

我很欣赏你的答案,我不熟悉不够用PROC数据集,现在使用这个权利,但会考虑它。如果我的声望足够高,我会给你一个满意的答复。 –

+0

@RMontgomery如果你需要重命名数据集'proc datasets'是最快的方法。如果用'copy'语句复制'proc copy'或'proc datasets'。如果在重写过程中实现一些逻辑,那么'数据步骤'。但对于像您这样的小数据集,无需专注于此。只要选择最适合你的方法。 – fl0r3k

+0

@ fl0r3k感谢您的信息,我正在阅读有关proc数据集。我将在更大的数据集上使用这些代码,以简化我们现有的流程,因此任何额外的效率可能都会更好。我必须继续阅读,谢谢! –