我有一个数组t,它指定了我想要从file.txt读取的行数。所以我的代码应该是这样的:
data a;
do i = 1 to dim(t);
infile "C:\sas\file.txt" firstobs = t(i) obs = t(i);
input x1-x10;
output;
end;
run;当然,这个解决方案(firstobs)只有在列数为常量的情况下才有效。如何使用数组(也是从同一文件中读取的-从第一行读取)来实现此目的?
例如,如果file.txt如下所示:
2 4 6 . . . . . . .
2 2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3 3
4 4 4 4 4 4 4 4 4
5 5 5 5 5 5 5 5 5
6 6 6 6 6 6 6 6 6然后我希望输出是:
2 2 2 2 2 2 2 2 2 2
4 4 4 4 4 4 4 4 4 4
6 6 6 6 6 6 6 6 6 6发布于 2015-11-06 00:28:57
听起来第一行包含要保留的行列表。从单独的文件中读取可能会更容易,但您可以让它与单个文件一起工作。您没有提到如何知道第一行中数据的列数或行号的最大数量。现在,让我们假设您可以在宏变量中设置这些数字。
让我们将您的示例数据放到一个文件中:
options parmcards=tempdata ;
filename tempdata temp;
parmcards;
2 4 6 . . . . . . .
2 2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3 3
4 4 4 4 4 4 4 4 4
5 5 5 5 5 5 5 5 5
6 6 6 6 6 6 6 6 6
;现在让我们把它读入一个数据集中。
%let ncol=9 ;
%let maxrows=1000;
data want ;
infile tempdata truncover ;
array rows (&maxrows) _temporary_;
if _n_=1 then do i=1 by 1 until (rows(i)=.);
input rows(i) @;
drop i;
end;
else do;
input x1-x&ncol;
if whichn(_n_,of rows(*)) then output;
end;
run; 如果文件的其他行包含无效数据,以至于INPUT语句将导致错误,您可以跳过尝试从这些行读取数据,只需在ELSE块中稍作修改即可。
else do;
input @;
if whichn(_n_,of rows(*)) then do;
input x1-x&ncol;
output;
end;
end;如果您发现经常不想在文件末尾读取大量记录,则可以将此行添加到数据步骤的末尾,以便在读取超过所需的最后一行时停止。
if _n_ > max(of rows(*)) then stop;发布于 2015-11-06 01:00:59
这是一个与Tom的答案类似的答案,但它不会尝试读入非路径数据。如果跳过的行包含的数据格式与路径上数据的格式不同,这可能会更好。它使用Tom的parmcard和结构,因此您可以更容易地看到不同之处。
options parmcards=tempdata ;
filename tempdata temp;
parmcards;
2 4 6 . . . . . . .
2 2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3 3
4 4 4 4 4 4 4 4 4
5 5 5 5 5 5 5 5 5
6 6 6 6 6 6 6 6 6
;
%let ncol=9 ;
%let maxrows=1000;
data want ;
infile tempdata truncover end=eof;
array rows (&maxrows) _temporary_;
do i=1 by 1 until (rows(i)=.); *read in first line, just like Toms answer;
input rows(i) @;
drop i;
end;
input ; * stop inputting on the first line;
* Here you may need to use CALL SORTN to sort row array if it is not already sorted;
_currow = 2; * current row indicator;
do _i = 1 to dim(rows); * iterate through row array;
if rows[_i]=. then leave; * leave if row array is empty;
do while (_currow lt rows[_i] and not eof); * skip rows not in row array;
input;
_currow = _currow + 1;
end;
input x1-x&ncol; * now you know you are on a desired row, so input it;
output; * and output it;
_currow = _currow + 1;
end;
run; 如上所述,如果数组尚未排序(即,如果未命中的数组不在末尾并且数字顺序混乱),您可能必须使用CALL SORTN。
发布于 2015-11-05 23:13:04
如果你的文件是结构化的(例如,相同的分隔符/输入数据的一个连续“行”),那么下面的方法应该是可行的。我确信您可以调整以提高效率,但我在其中添加了一些注释,以解释每个部分都在做什么。我还建议通读infile文档,以获得_infile_自动变量的解释以及操纵输入数据缓冲区的其他方法。此外,如果您的输入数据文件本身需要拆分成单独的行,那么您将需要进行相应的调整。
filename in_data 'C:\sas\file.txt';
data out_data (keep=x1-x10);
infile in_data;
input fn;
/*get the number of vars based on delimiter*/
count = count(strip(_infile_), ' ') + 1;
/*iterate through vars*/
do i =1 to count;
/*set new value to current var*/
rec = scan(strip(_infile_), i, ' ');
/*set array values to new value*/
array obs(10) x1-x10;
do j=1 to dim(obs);
obs(j) = rec;
end;
/*output to dataset*/
output out_data;
end;
run;输入
2 4 6 7 8 9 10 11 2 3 输出
x1 x2 x3 x4 x5 x6 x7 x8 x9 x10
2 2 2 2 2 2 2 2 2 2
4 4 4 4 4 4 4 4 4 4
6 6 6 6 6 6 6 6 6 6
7 7 7 7 7 7 7 7 7 7
8 8 8 8 8 8 8 8 8 8
9 9 9 9 9 9 9 9 9 9
10 10 10 10 10 10 10 10 10 10
11 11 11 11 11 11 11 11 11 11
2 2 2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3 3 3希望这能有所帮助。
https://stackoverflow.com/questions/33540652
复制相似问题