BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Phil_NZ
Barite | Level 11

Hi all SAS users,

 

Today I am trying  to understand the usage of _N_, when looking at the link , I saw an example that the author used to create the dataset:

data have;
input x @@;
datalines;
1 2 3
;

I am not familiar with the character"@@" so I did a search, and from what I search, I still cannot clarify what does "@@" actually do and how it work, could you please explain it to me and how it works in the above code?

 

Warmest regards.

Thank you for your help, have a fabulous and productive day! I am a novice today, but someday when I accumulate enough knowledge, I can help others in my capacity.
1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

Work it out.  Change the line(s) of data and see what happens.

 

 

Spoiler

On the first iteration the pointer starts in column 1.  Then after reading the first value the point moves to after the value. Since the first value is one character the pointer moves one column to read that and then another column to read the delimiter so it end at column 3.  Since you used double @ on the second iteration the pointer starts at three.  ....

 

On the fourth iteration the pointer starts in column 7, which is past the last non-blank character in the line.  So it flows over to the next line to find a value to read.  But since there is no next line the data step ends right there.

 

View solution in original post

5 REPLIES 5
ChrisNZ
Tourmaline | Level 20

@@  insures that the pointer will not go to the next data line as the data step loop iterates.

so 1 will be read, then the pointer stays on the same line and 2 is read, etc.

Tom
Super User Tom
Super User

The documentation describes it. 

@@

holds an input record for the execution of the next INPUT statement across iterations of the DATA step. This line-hold specifier is called double trailing @.

Restriction The double trailing @ must be the last item in the INPUT statement.
Tip The double trailing @ is useful when each input line contains values for several observations.
See Using Line-Hold Specifiers

 

Try experimenting and see what you can figure out.

 

data have;
  input x @@;
  put _n_= x= ;
datalines;
1 2 3
;

See what happens if you use the COLUMN= option on the INFILE statement.

data have;
  infile datalines column=cc ;
  put _n_= cc= ;
  input x @@;
  put _n_= cc= x= ;
datalines;
1 2 3
;

 

 

Phil_NZ
Barite | Level 11

Hi @ChrisNZ  and @Tom 

 

Thank you for your explanation, now I can imagine how it works generally. Generally speaking, it jumps to read the number on column 1, 3, 5  on the same line (associated with value 1,2,3) after each iteration, and there are three iterations in total.

Just some curiosity about the example of @Tom:

From what I searched, "COLUMN Input specifies the columns to be read for each variable". Regarding the first iteration for the code given

data have;
  infile datalines column=cc ;
  put _n_= cc= ;
  input x @@;
  put _n_= cc= x= ;
datalines;
1 2 3
;

The log is

_N_=1 cc=1
_N_=1 cc=3 x=1
_N_=2 cc=3
_N_=2 cc=5 x=2
_N_=3 cc=5
_N_=3 cc=7 x=3
_N_=4 cc=7
NOTE: SAS went to a new line when INPUT statement reached past the end of a line.

I am wondering why when cc=3, x should equal to 1 because column 3 of the data lines is "2", not "1". Or cc is the pointer position after the first iteration being executed ? 

 

Could you please explain to me if I fell into any fallacy?

 

Warm regards.

Thank you for your help, have a fabulous and productive day! I am a novice today, but someday when I accumulate enough knowledge, I can help others in my capacity.
Tom
Super User Tom
Super User

Work it out.  Change the line(s) of data and see what happens.

 

 

Spoiler

On the first iteration the pointer starts in column 1.  Then after reading the first value the point moves to after the value. Since the first value is one character the pointer moves one column to read that and then another column to read the delimiter so it end at column 3.  Since you used double @ on the second iteration the pointer starts at three.  ....

 

On the fourth iteration the pointer starts in column 7, which is past the last non-blank character in the line.  So it flows over to the next line to find a value to read.  But since there is no next line the data step ends right there.

 

FreelanceReinh
Jade | Level 19

Hi  @Phil_NZ,


@Phil_NZ wrote:

From what I searched, "COLUMN Input specifies the columns to be read for each variable".

(...)

Could you please explain to me if I fell into any fallacy?


It appears that you misinterpreted the COLUMN= option of the INFILE statement as an indication of column input. However, your INPUT statement performs list input, not column input. The COLUMN= option can be used with all four input styles. For example, it can help you to see one of the differences between list input and column input (in fact between list input and the three other input styles): The position of the input pointer after reading a value.

data test;
infile cards column=c;
input x 1; /* Column input (1 is the column number). Without the "1" it would  */
put x= c=; /* be list input. Note how x and c differ between the two versions. */
cards;
85
;

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!

Submit your idea!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 5 replies
  • 760 views
  • 4 likes
  • 4 in conversation