Csv 强制proc export为不存在的变量创建空白列 背景

Csv 强制proc export为不存在的变量创建空白列 背景,csv,sas,export,sas-macro,Csv,Sas,Export,Sas Macro,我正在运行下面的宏来导出循环中的许多数据集。不幸的是,其中一些数据集有额外的变量。我的目的是以相同的格式导出所有文件,其中不存在的列作为空格提供 资料 这可以用以下数据集来说明 dataA dataB dataC 我希望我的CSV文件如下所示: dataA.CSV dataB.CSV dataC.CSV 宏 总结 换句话说,我想修改proc export的行为,以创建不存在的var,如果在Kepp=中传递了这样的var。当然,这将失败,因为sashelp.class没有不存在的var,但这是我想

我正在运行下面的宏来导出循环中的许多数据集。不幸的是,其中一些数据集有额外的变量。我的目的是以相同的格式导出所有文件,其中不存在的列作为空格提供

资料 这可以用以下数据集来说明

dataA
dataB
dataC
我希望我的CSV文件如下所示:

dataA.CSV
dataB.CSV
dataC.CSV
宏 总结 换句话说,我想修改
proc export
的行为,以创建
不存在的var
,如果在
Kepp=
中传递了这样的var。当然,这将失败,因为
sashelp.class
没有
不存在的var
,但这是我想要模拟的行为

proc export data=sashelp.class (keep =  name
                                        sex
                                        NonExistingVar)
   outfile="/stuff/proc_test.csv"
   dbms=csv
   replace;
run;

如果您在某个地方有一个宏变量,其中包含要导出的列的列表,则可以构造一个包含这些列的视图,包括基础数据集中不存在的列,然后改为导出该视图。例如

%let keepcols = sex weight newcol;

data t_view /view = t_view;
  if 0 then set sashelp.class; 
  if _n_ = 1 then call missing(of &keepcols);
  set sashelp.class;
run;
if 0 then set xyz
是一个很好的小技巧,它允许您保留列顺序、长度和类型,而不必从第一个set语句中读取任何行。当随后将变量设置为缺少的值时,它避免了类型冲突-我们必须将它们初始化为其他值,否则它们不会输出。然后,第二个set语句将覆盖实际存在的变量的缺失值

如果您查询元数据表以确定保留的列中有哪些列,那么这可能会变得更有效,因此您将只加载那些列,但对于大多数情况来说,这应该是合理的

延迟选项是临时禁用与保留相关的错误和警告,例如:

%let keepcols = sex weight newcol;

%let dkricond = %sysfunc(getoption(dkricond)); /*Save for later*/
option dkricond = nowarn;

data t_view /view = t_view;
  if 0 then set sashelp.class(keep = &keepcols); /*Normally this would trigger an error or warning*/
  retain &keepcols;
  set sashelp.class(keep = &keepcols); 
run;

option dkricond = &dkricond; /*Restore original setting*/

如果您在某个地方有一个宏变量,其中包含要导出的列的列表,则可以构造一个包含这些列的视图,包括基础数据集中不存在的列,然后改为导出该视图。例如

%let keepcols = sex weight newcol;

data t_view /view = t_view;
  if 0 then set sashelp.class; 
  if _n_ = 1 then call missing(of &keepcols);
  set sashelp.class;
run;
if 0 then set xyz
是一个很好的小技巧,它允许您保留列顺序、长度和类型,而不必从第一个set语句中读取任何行。当随后将变量设置为缺少的值时,它避免了类型冲突-我们必须将它们初始化为其他值,否则它们不会输出。然后,第二个set语句将覆盖实际存在的变量的缺失值

如果您查询元数据表以确定保留的列中有哪些列,那么这可能会变得更有效,因此您将只加载那些列,但对于大多数情况来说,这应该是合理的

延迟选项是临时禁用与保留相关的错误和警告,例如:

%let keepcols = sex weight newcol;

%let dkricond = %sysfunc(getoption(dkricond)); /*Save for later*/
option dkricond = nowarn;

data t_view /view = t_view;
  if 0 then set sashelp.class(keep = &keepcols); /*Normally this would trigger an error or warning*/
  retain &keepcols;
  set sashelp.class(keep = &keepcols); 
run;

option dkricond = &dkricond; /*Restore original setting*/

要使其工作,您需要有一个要输出的变量列表。假设有一个宏变量和这个列表

%let varlist=varA varB varC ;
因为您正在编写CSV文件,所以只需直接使用数据步骤即可,并且避免使用PROC EXPORT。在数据步骤中,如果您引用了一个不存在的变量,SAS会很乐意为您创建一个空变量

您可能需要有点创造性才能添加标题记录。这里有一种使用TRANWRD()函数的方法,当每个变量名之间只有一个空格时,该方法就可以工作。注意,您可以使用COMPBL()实现这一点

%let varlist=Name Unknown    Age ;
%let varlist=%sysfunc(compbl(&varlist));

data _null_;
  file "/stuff/proc_test.csv" dsd ;
  if _n_=1 then put "%sysfunc(tranwrd(&varlist,%str( ),%str(,)))" ;
  set sashelp.class ;
  put &varlist ;
run;
结果:

Name,Unknown,Age
Alfred,,14
Alice,,13
Barbara,,13
Carol,,14
Henry,,14
James,,12
Jane,,12
Janet,,15
Jeffrey,,13
John,,12
Joyce,,11
Judy,,14
Louise,,12
Mary,,15
Philip,,16
Robert,,12
Ronald,,15
Thomas,,11
William,,15

要使其工作,您需要有一个要输出的变量列表。假设有一个宏变量和这个列表

%let varlist=varA varB varC ;
因为您正在编写CSV文件,所以只需直接使用数据步骤即可,并且避免使用PROC EXPORT。在数据步骤中,如果您引用了一个不存在的变量,SAS会很乐意为您创建一个空变量

您可能需要有点创造性才能添加标题记录。这里有一种使用TRANWRD()函数的方法,当每个变量名之间只有一个空格时,该方法就可以工作。注意,您可以使用COMPBL()实现这一点

%let varlist=Name Unknown    Age ;
%let varlist=%sysfunc(compbl(&varlist));

data _null_;
  file "/stuff/proc_test.csv" dsd ;
  if _n_=1 then put "%sysfunc(tranwrd(&varlist,%str( ),%str(,)))" ;
  set sashelp.class ;
  put &varlist ;
run;
结果:

Name,Unknown,Age
Alfred,,14
Alice,,13
Barbara,,13
Carol,,14
Henry,,14
James,,12
Jane,,12
Janet,,15
Jeffrey,,13
John,,12
Joyce,,11
Judy,,14
Louise,,12
Mary,,15
Philip,,16
Robert,,12
Ronald,,15
Thomas,,11
William,,15

为什么调用missing()?在设置任何值之前,您仅在第一次传递时使用它,因此这些值已经丢失。你是不是想阻止日志中关于未初始化变量的注释?@Tom如果没有它,输入数据集中不存在的任何“额外”变量都不包括在输出视图中。通常,对于这种类型的视图,人们使用
RETAIN
语句强制变量的顺序/创建,而不强制变量的数据类型<代码>数据。。。;保留&varlist;设置保存&varlist;运行足够公平-这有点短。为什么
调用missing()
?在设置任何值之前,您仅在第一次传递时使用它,因此这些值已经丢失。你是不是想阻止日志中关于未初始化变量的注释?@Tom如果没有它,输入数据集中不存在的任何“额外”变量都不包括在输出视图中。通常,对于这种类型的视图,人们使用
RETAIN
语句强制变量的顺序/创建,而不强制变量的数据类型<代码>数据。。。;保留&varlist;设置保存&varlist;运行足够公平-稍微短一点。
%let varlist=Name Unknown    Age ;
%let varlist=%sysfunc(compbl(&varlist));

data _null_;
  file "/stuff/proc_test.csv" dsd ;
  if _n_=1 then put "%sysfunc(tranwrd(&varlist,%str( ),%str(,)))" ;
  set sashelp.class ;
  put &varlist ;
run;
Name,Unknown,Age
Alfred,,14
Alice,,13
Barbara,,13
Carol,,14
Henry,,14
James,,12
Jane,,12
Janet,,15
Jeffrey,,13
John,,12
Joyce,,11
Judy,,14
Louise,,12
Mary,,15
Philip,,16
Robert,,12
Ronald,,15
Thomas,,11
William,,15