在SAS中输入数组

时间:2016-03-14 12:17:18

标签: sas

我需要将多个原始文本文件读入SAS数据集。每个文件包含几个成分,如下面的示例文件所示。每个文件(一个菜)列出一行中的所有成分,用逗号分隔。成分的量是可变的。一些示例文件(菜肴):

示例文件1(dish1.csv):

  

Tomate,Cheese,Ham,Bread

示例文件2(dish2.csv):

  

Sugar,Apple

示例文件3(dish3.csv):

  

牛奶,糖,可可

因为我有大约250个文件(菜肴),所以我创建了一个宏程序来读取这些文件。这样我就可以在另一个宏中执行这个宏来读取我需要的所有菜肴。该计划如下:

%readDish (dishNumber);
    data newDish;
        * Find and read the csv-file;
        infile "my_file_location/dish&dishNumber..csv" dlm=";" missover;

        * Read up to 25 ingredients;
        input ingredient1-ingredient25 : $25.;

        * Put all ingredients in an array;
        array ingredients{25} ingredient1-ingredient25;

        * Loop thrue all the ingredients and output;
        do i=1 to dim(ingredients);
            dishNumber = &dishNumber;
            ingredient = ingredients{i};
            output;
        end;
    run;
%mend;

是否有可能创建一个能够读取所有菜肴的SAS(宏)程序,无论我有多少成分? SAS表应如下所示:

1 Tomate
1 Cheese
1 Ham
1 Bread

1 个答案:

答案 0 :(得分:1)

对我来说似乎很简单:垂直读取数据,然后如果需要水平,则在之后添加转置步骤。您不必一步一步地读取整行 - @@运算符告诉SAS将行指针保留在该行上,因此您只需读取该行。

data dishes;
  length _file $1024 
         ingredient $128;
  infile "c:\temp\dish*.csv" dlm=',' filename=_file lrecl=32767; *or whatever your LRECL needs to be;
  input ingredient $ @@;
  dishnumber = input(compress(scan(_file,-2,'\.'),,'kd'),12.);
  output;
run;

在这里,我使用通配符将它们全部读入 - 当然,如果需要,我们可以使用类似代码的宏,尽管通配符或连接文件名可能更容易。我获取dishnumber的方式可能并不总是有效,具体取决于文件名构造,但某些形式的应该是可用的。

扩展其工作原理:datastep在SAS中的工作方式是它是一个循环,循环遍历代码,直到遇到“结束条件”。结束条件最常见的是stop关键字,然后是从SET或INFILE读取的任何尝试都不可能进一步读取(即,您读取100行SAS数据集,并尝试读取第101行) in,失败,所以结束数据步骤)。但是,除此之外,它将继续执行相同的代码,直到它到达那里。它只是在“运行”点进行一些清理,以确保它不是无限循环。

在从infiles输入的情况下,通常SAS读取一行,然后在RUN中,它将跳转到下一个EOL(行尾,通常是回车和Windows中的换行),如果它还没有在一个行。有时这很有用 - 通常也许。但是,在某些情况下,你宁愿让SAS继续读同一行。

来自@@运算符。 @@说“即使你打RUN也不要进入EOL”。 (@说“除非你按下RUN,否则不要前进到EOL” - 通常输入本身会导致SAS读取直到EOL。)因此,当你执行下一个数据步骤迭代时,输入指针将在同一个你离开它的确切位置 - 就在你读到的前一个字段之后。

这在60年代和70年代非常有用,当时标签卡是时髦的新东西,你会经常输入输入线而不考虑任何线条组织 - 特别是,如果你每行只输入一个变量,那么8每个输入变量的列,你不会从一个穿孔卡中浪费72个块 - 所以,你输入的就像你的成分一样:输入上每行有很多数据,然后想要在每行中转换成一行数据记忆。虽然现在以这种方式存储数据并不常见,但这肯定是可能的 - 正如您的数据所示。