Sas 如何在没有标题的上游平面文件中更改结构后生成新的导入代码?

Sas 如何在没有标题的上游平面文件中更改结构后生成新的导入代码?,sas,Sas,我有一个现有的进程,可以从没有标题的平面文件导入数据。有数百列。该文件的提供者在现有列的不同位置又添加了数百列。我有一个新旧列名的列表,以及正确设置旧列(而不是新列)数据类型的SAS代码。我不想查看我现有的导入代码并手动编写列标题和数据格式,但我不确定如何使用这些部分为新标题获取新的导入代码 data raw_file; infile "flatfile.csv" delimiter="|" missover dsd firstobs=1; informat oldcol1 best32.; i

我有一个现有的进程,可以从没有标题的平面文件导入数据。有数百列。该文件的提供者在现有列的不同位置又添加了数百列。我有一个新旧列名的列表,以及正确设置旧列(而不是新列)数据类型的SAS代码。我不想查看我现有的导入代码并手动编写列标题和数据格式,但我不确定如何使用这些部分为新标题获取新的导入代码

data raw_file;
infile "flatfile.csv" delimiter="|" missover dsd firstobs=1;
informat oldcol1 best32.;
informat oldcol2 mmddyy10.;
informat oldcolN $60.;
format oldcol1 best32.;
format oldcol2 mmddyy10.;
format oldcolN $60.;
input
oldcol1 
oldcol2 
oldcolN $;
run;
我现在在Excel文件中有标题信息。

旧K010H K010I K010J K020A

新K010H K010I K010J K010L K010M K010N K020A

如果您有一个机器可读的数据字典,那么您可以从中生成代码。否则,只需编辑数据步骤。当你在它,你可以清理它,以便更容易维护

第一件事是使用LENGTH或ATTRIB来定义变量,而不是强迫sa猜测。第二,仅将信息或格式附加到需要它们的变量。例如,不需要将信息附加到普通字符串或数字。无需将$xx格式附加到字符变量。你真的需要附上BEST32吗。格式化为数字,而不是让SAS继续,并使用默认的BEST12显示没有附加格式的数字变量。格式

其次,如果按照变量的显示顺序定义变量,则可以在输入语句中使用位置变量列表。然后,如果第一个或最后一个变量发生更改,则只需更改输入语句

因此,对于您的示例,您可能会创建这样的数据步骤

data raw_file;
  infile "flatfile.csv" dlm="|" truncover dsd firstobs=1;
  length 
     oldcol1 8
     oldcol2 8
     oldcolN $60
  ;
  informat oldcol2 mmddyy10.;
  format oldcol2 mmddyy10.;
  input oldcol1 -- oldcolN ;
run;

然后添加新变量非常简单,只需将它们插入LENGTH语句中的正确位置,并在需要时将它们添加到INFORMAT和/或FORMAT语句中。如果您不知道变量包含哪些内容,请将其作为字符串,查看结果值,然后决定是否需要对其进行不同的定义。

根据您的描述,我假定您知道或将找到新列的信息。如果是这样,为什么不自动生成代码来读取文件

由于您有标题信息,假设您可以将其修改为以下格式并另存为CSV:

var     infmt
K010H   best32.
K010I   mmddyy10.
K010J   $60. 
K010L   best32.
K010M   mmddyy10.
K010N   $60. 
K020A   best32.
这样会自动生成代码并为您读取数据:

proc import datafile="cols.csv" out=cols replace;
run;

proc sql;
  select var into :cols separated by ' ' from cols ;
  select infmt into :infmts separated by ' ' from cols ;
  quit;

%macro gen_code;

  data raw_file;
    infile "flatfile.csv" delimiter="|" missover dsd firstobs=1;

    %let ii = 1;
    %do %while (%scan(&cols, &ii, %str( )) ~= %str());
      %let col = %scan(&cols, &ii, %str( ));
      %let infmt = %scan(&infmts, &ii, %str( ));
      informat &col &infmt ;
      %let ii = %eval(&ii + 1);
    %end;

    input
    %let ii = 1;
    %do %while (%scan(&cols, &ii, %str( )) NE %str());
      %let col = %scan(&cols, &ii, %str( ));
      &col 
      %let ii = %eval(&ii + 1);
    %end;
   ;
 run;

%mend;

%gen_code;

将来,您可以对头CSV文件进行修改,其余部分将由代码本身处理。

能否显示列表示例。如果我理解正确,您需要更改进程以读取列表(元数据),并对数据步骤进行编码以读取文件。我添加了一个示例,说明我如何看到标题中的差异。是否有基于旧列名为新列名分配属性的模式?例如,这句话是否恰当?所有
K010
列都应该有相同的属性我认为有,但有很多新列,所以可能不是所有列都有相同的属性。@BenjaminCrane你是说“提供者”没有提供列出每个字段和相关属性的文档吗?这正是我要找的。我喜欢这样,如果他们将来做出这样的重大更改,我将能够更轻松地进行更改。有用的信息,特别是关于改进数据步骤并使其更适合的方法。