4

这似乎应该很简单,但我在文档中找不到如何做到这一点。我想读一个逗号分隔的文件,但它很宽,我只想读几列。

我以为我可以这样做,但@指针似乎指向文本的列,而不是由分隔符定义的列号:

data tmp;
 infile 'results.csv' delimiter=',' MISSOVER DSD lrecl=32767 firstobs=2;
 @1 id
 @5 name$
run;

在此示例中,我想根据分隔符仅读取第 1 列和第 5 列中的内容,但 SAS 正在读取文本文件位置 1 和位置 5 中的内容。所以如果输入文件的第一行是这样开始的

1234567, "x", "y", "asdf", "bubba", ... 更多变量 ...

我想要id=1234567name=bubba,但我得到name=567, "

我意识到我可以阅读每一列并删除我不想要的那些,但必须有更好的方法。

4

3 回答 3

6

实际上,@ 确实指向文本列而不是分隔列。我发现的唯一使用标准输入的方法是读取空白,即

input
id
blank $
blank $
blank $ 
name $
;

然后留空。

但是,如果您不介意以不同的方式编写输入,则有更好的解决方案。

data tmp;
 infile datalines;
 input @;
 id = scan(_INFILE_,1,',');
 name = scan(_INFILE_,5,',');
 put _all_;
 datalines;
12345,x,y,z,Joe
12346,x,y,z,Bob
;;;;
run;

它使格式化稍微复杂一些,因为您需要为每个您不想要的基本字符格式的变量设置 put 或 input 语句,但根据您的需要,它可能会更容易。

于 2012-09-20T13:52:01.570 回答
1

如果您了解一点 INPUT 语句语法,则可以相当有效地跳过字段,请注意 (3*dummy)(:$1.) 的使用。只读取一个字节也应该会稍微提高性能。

data tmp;
   infile cards DSD firstobs=2;
   input id $ (3*dummy)(:$1.) name $;
   drop dummy;
   cards;
id,x,y,z,name
1234567, "x", "y", "asdf", "bubba", ... more variables 
1234567, "x", "y", "asdf", "bubba", ... more variables 
   run;
proc print;
   run;
于 2015-09-29T13:58:47.060 回答
0

我在回答其他用户的相关问题时想到的另一个选项。

filename  tempfile temp;

data _null_;
  set sashelp.cars;
  file tempfile dlm=',' dsd lrecl=32767;
  put (Make--Wheelbase) ($);
run;


data mydata;
  infile tempfile dlm=',' dsd truncover lrecl=32767;
  length _tempvars1-_tempvars100 $32;
  array _tempvars[100] $;
  input (_tempvars[*]) ($);
  make=_tempvars[1];
  type=_tempvars[3];
  MSRP=input(_tempvars[6],dollar8.);
  keep make type msrp;
run;

在这里,我们使用一组有效的临时变量(不幸的是,实际上不能是临时变量),然后获取我们想要指定列的内容。这对于一个小文件来说可能是多余的——只需读入所有变量并处理它——但对于 100 或 200 个变量,你只需要 15、18 和 25,这可能更容易,只要你知道你在哪一列正是想要。(我可以看到在处理人口普查数据时使用它,例如,如果你有 CSV 格式的数据。只需要几列是很常见的,其中大多数列比起始列低 100 或 200 列。)

您必须注意临时数组的长度(必须与您关心的最长列一样长!),并且您必须确保不要弄乱列,因为您不会知道如果你搞砸了,除非从数据中很明显。

于 2015-02-13T20:57:42.360 回答