SAS PROC导入多个SAV文件-强制SPSS值标签创建唯一的SAS格式名称

SAS PROC导入多个SAV文件-强制SPSS值标签创建唯一的SAS格式名称,sas,spss,Sas,Spss,有时,如果我将多个SAV文件导入SAS工作库,则稍后导入的一个变量将覆盖先前导入的具有类似名称的变量的显示文本(即格式) 我确定这是因为后一个数据集的变量为自定义格式(来自SPSS值标签)生成了一个格式名称,该名称与前一个变量的格式名称相同,即使变量在SAV文件的值标签属性中有不同的定义 在自动命名新的自定义格式之前,是否有办法通过在PROC IMPORT自动检查工作库格式库中是否已存在格式名称,从而强制SAS不重复使用相同的格式名称?或者有没有其他方法可以防止这种情况发生 这是我的代码以及变量

有时,如果我将多个SAV文件导入SAS工作库,则稍后导入的一个变量将覆盖先前导入的具有类似名称的变量的显示文本(即格式)

我确定这是因为后一个数据集的变量为自定义格式(来自SPSS值标签)生成了一个格式名称,该名称与前一个变量的格式名称相同,即使变量在SAV文件的值标签属性中有不同的定义

在自动命名新的自定义格式之前,是否有办法通过在PROC IMPORT自动检查工作库格式库中是否已存在格式名称,从而强制SAS不重复使用相同的格式名称?或者有没有其他方法可以防止这种情况发生

这是我的代码以及变量名、格式名等的示例

proc import out=Dataset1 datafile="S:\folder\Dataset1.SAV"
dbms=SAV replace; 
run;
proc import out=DatasetA datafile="S:\folder\DatasetA.SAV"
dbms=SAV replace; 
run;
数据集1包含变量问题1。原始SPSS值标签为1=是2=否。导入此数据集时,SAS会自动为问题1生成格式名称QUESTION。当仅导入Dataset1时,格式的定义将出现问题。对应于Dataset1.SAV中问题_1的SPSS值标签

数据集包含变量问题A和SPSS值标签1=同意2=不确定3=不同意。在Dataset1之后导入此数据集时,SAS会自动生成格式名称问题。对于问题A,即使工作库已包含名为Question.的格式。。因此,这覆盖了格式问题的定义。这是在导入Dataset1时生成的。导入DatasetA后,格式的定义将出现问题。对应于DatasetA.SAV中问题_A的SPSS值标签

因此,当Dataset1和DatasetA都被导入时,变量Question_1和Question_A都被分配了格式名称Question,以及格式问题的定义。在SAS工作文件夹中,对应于DatasetA.SAV中的SPSS值标签,而不是Dataset1.SAV。因此,问题_1将显示为1=同意2=不确定,即使变量值实际上意味着1=是2=否

理想情况下,我希望这两个变量在导入步骤自动生成不同的自定义格式名称。有什么办法可以做到这一点吗?或者,是否有其他方法可以防止发生这种类型的覆盖


谢谢。

防止文字覆盖的方法是为使用FMTLIB=optional语句读取的每个SPSS文件指向不同格式的目录

proc import out=dataset1 replace 
   datafile="S:\folder\Dataset1.SAV" dbms=SAV 
; 
   fmtlib=work.fmtcat1;
run;
proc import out=dataset2 replace 
   datafile="S:\folder\Dataset2.SAV" dbms=SAV 
; 
   fmtlib=work.fmtcat2;
run;
然后,您可以稍后重命名冲突格式(并更改数据集中的附加格式以使用新名称)

因此,如果成员名称和格式名称足够短,您应该能够通过附加这两个名称来生成一个唯一的新名称(在两者之间添加一些内容以避免冲突)。因此,类似这样的操作将重命名格式,更改附加到变量的格式名称,并将格式重新构建到WORK.formats目录中

%macro sav_import(file,memname);
%if 0=%length(&memname) %then %let memname=%scan(&file,-2,\./);

proc import datafile=%sysfunc(quote(&file)) dbms=save
  out=&memname replace
; 
  fmtlib=work.&memname ;
run;

proc format lib=work.&memname cntlout=formats;
run;

data formats ;
  set formats end=eof;
  by fmtname type notsorted;
  oldname=fmtname;
  fmtname=catx('_',"&memname",oldname);
run;

proc contents data=&memname noprint out=contents;
run;

proc sql noprint;
  select distinct catx(' ',c.name,cats(f.fmtname,'.'))
    into :fmtlist separated by ' '
  from contents c inner join formats f
  on c.format = f.oldname
  ;
quit;

proc datasets nolist lib=work;
  modify &memname;
    format &fmtlist ;
  run;
quit;

proc format lib=work.formats cntlin=formats;
run;

%mend sav_import;

%sav_import(S:\folder\Dataset1.SAV);
%sav_import(S:\folder\Dataset2.SAV);

防止文字覆盖的方法是使用FMTLIB=optional语句为正在读取的每个SPSS文件指向不同格式的目录

proc import out=dataset1 replace 
   datafile="S:\folder\Dataset1.SAV" dbms=SAV 
; 
   fmtlib=work.fmtcat1;
run;
proc import out=dataset2 replace 
   datafile="S:\folder\Dataset2.SAV" dbms=SAV 
; 
   fmtlib=work.fmtcat2;
run;
然后,您可以稍后重命名冲突格式(并更改数据集中的附加格式以使用新名称)

因此,如果成员名称和格式名称足够短,您应该能够通过附加这两个名称来生成一个唯一的新名称(在两者之间添加一些内容以避免冲突)。因此,类似这样的操作将重命名格式,更改附加到变量的格式名称,并将格式重新构建到WORK.formats目录中

%macro sav_import(file,memname);
%if 0=%length(&memname) %then %let memname=%scan(&file,-2,\./);

proc import datafile=%sysfunc(quote(&file)) dbms=save
  out=&memname replace
; 
  fmtlib=work.&memname ;
run;

proc format lib=work.&memname cntlout=formats;
run;

data formats ;
  set formats end=eof;
  by fmtname type notsorted;
  oldname=fmtname;
  fmtname=catx('_',"&memname",oldname);
run;

proc contents data=&memname noprint out=contents;
run;

proc sql noprint;
  select distinct catx(' ',c.name,cats(f.fmtname,'.'))
    into :fmtlist separated by ' '
  from contents c inner join formats f
  on c.format = f.oldname
  ;
quit;

proc datasets nolist lib=work;
  modify &memname;
    format &fmtlist ;
  run;
quit;

proc format lib=work.formats cntlin=formats;
run;

%mend sav_import;

%sav_import(S:\folder\Dataset1.SAV);
%sav_import(S:\folder\Dataset2.SAV);

谢谢你,汤姆。这是有道理的,因为它不能更自动地完成。我一次处理两个以上的数据集,每个数据集有数百个变量,所以我希望尽可能多地实现自动化。下面是我将要做的事情,以便按照您所描述的那样修复它。如果您看到任何更有效的建议,我将不胜感激:(1)获取变量名+格式名的元数据数据集。(2) 合并以仅保存非唯一格式名称+在哪些数据集中为其分配了哪些变量。(3) 获取格式名称及其定义的数据集(每行一个值,使用(续)proc format cntlout=)。(4) 仅将格式定义数据集限制为非唯一格式名称。(5) 按格式名称、变量值和值定义相互合并这些非唯一格式名称格式定义数据集。(6) 保存定义存在差异的行(即,格式名称匹配但值仅为一种格式,或值以两种格式定义但值定义不同)。(7)使用此列表返回并保存存在任何此类差异的非唯一格式名称的所有行(此步骤的产品=任何非唯一格式名称的格式名称、值(续)和值定义列表,这些名称在不同数据集中的定义不同,还包括在不同数据集中分配给格式的变量名称)。(8)手动重命名单独FMTLIB中的格式并重新分配给变量(或者这可能必须在工作库中完成后才能完成-这将很容易解决)。(9)将所有单独FMTLIB的内容保存到工作库中,以便数据集可以正常使用。感谢您考虑我的后续问题(也是为了澄清,当我在步骤(8)中说“手动重命名”时)我的意思是,检查和决策过程需要手动进行,重命名和重新分配格式的语法必须针对特定的格式名称/变量编写。如果由PROC导入创建的格式是简单的值->标签映射,则可以使用PROC format的CNTLOUT=选项将其转换为数据。然后可以进行搜索用于名称冲突,并具有重命名格式的规则。或者您可以