Hello! I have 2 rows of data;
2010 2011 2012 2013 2014 2015
13456 15673 12003 18546 14111 13872
I want to import this data with only 1 data step so that my first row (representing years) becomes column "years" and my second row (representing income) becomes column "income".
I have tried a lot, like using @@, : and so on. Nothing seems to work. Maybe someone over here can give me a hint. Thank you.
It can be done also using two filenames pointing to your data file:
filename x1 "/home/.../Two lines of data.txt";
filename x2 "/home/.../Two lines of data.txt";
data want;
infile x1 firstobs=1 obs=1 truncover;
input year @@;
if missing(year) then stop;
infile x2 firstobs=2 obs=2;
input income @@;
output;
run;
Do you know how many there are in advance?
data want;
infile myfile truncover length=ll column=cc;
input year1-year6 / income1-income6 ;
array y [6] ;
array i [6] ;
do row=1 to 6;
year=y[row];
income=i[row];
output;
end;
keep row year income;
run;
If not then just make the array larger than you could need and count how many years there so you know how many incomes to read.
data want;
array y [1000] _temporary_;
infile myfile truncover length=ll column=cc;
do row=1 by 1 until (cc>ll);
input y[row] @@;
end;
input;
do row=1 to row ;
year=y[row];
input income @@;
output;
end;
run;
options parmcards=x;
filename x temp;
parmcards;
2010 2011 2012 2013 2014 2015
13456 15673 12003 18546 14111 13872
;
data want;
infile x length=len;
length first second $ 2000;
retain first;
if _n_=1 then input first $varying2000. len;
if _n_=2 then do;
input second $varying2000. len;
do i=1 to countw(first);
year=input(scan(first,i),best32.);
income=input(scan(second,i),best32.);
output;
end;
end;
keep year income;
run;
It can be done also using two filenames pointing to your data file:
filename x1 "/home/.../Two lines of data.txt";
filename x2 "/home/.../Two lines of data.txt";
data want;
infile x1 firstobs=1 obs=1 truncover;
input year @@;
if missing(year) then stop;
infile x2 firstobs=2 obs=2;
input income @@;
output;
run;
The key trick there is two make the data step believe it is reading form two different files otherwise it only opens the file once in spite of two infile statements.
So you could use two different filerefs.
filename file1 "c:\downloads\sample.txt" ;
filename file2 "%sysfunc(pathname(file1))";
data want;
infile file1 obs=1;
input year @@;
infile file2 firstobs=2;
input income @@;
run;
Or a fileref and a physical path.
filename file1 "c:\downloads\sample.txt" ;
data want;
infile file1 obs=1;
input year @@;
infile "%sysfunc(pathname(file1))" firstobs=2;
input income @@;
run;
Or just two different paths that point to the same file.
data want;
infile "c:\downloads\sample.txt" obs=1;
input year @@;
infile "c:\downloads\.\sample.txt" firstobs=2;
input income @@;
run;
@Tom - But, I used exactly the same filepath for both filenames, and it worked. I'm on SODA (Unix servers, I guess).
Thank you all so much for your solutions!
These solutions started me thinking ... would there be any value to SAS implementing column pointers for each row of the input buffer? For example, could this approach be made to work with some tweaks to the software?
data want;
infile rawdata stopover;
input #1 year #2 income @@;
run;
And would this be a tiny step toward implementing some functionality of Python or R within the SAS software?
It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.
SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.
Find more tutorials on the SAS Users YouTube channel.