You mean to build a dynamically lag? As far as I know that couldn't be done using the lag function. Another possibility is to you the absolute with itself using absolute and relative row numbers in the join expression:
obsNum = _n_;
create table output as
select n, P, Pn
from YourData as a
left join YourData as b
on a.obsNum - n = b.obsNum
The documentation on the LAG function explains that
"The LAG functions, LAG1, LAG2, ..., LAG100 return values from a queue. LAG1 can also be written as LAG. A LAGn function stores a value in a queue and returns a value stored previously in that queue. Each occurrence of a LAGn function in a program generates its own queue of values.
The queue for LAGn is initialized with n missing values, where n is the length of the queue (for example, a LAG2 queue is initialized with two missing values). When LAGn is executed, the value at the top of the queue is removed and returned, the remaining values are shifted upwards, and the new value of the argument is placed at the bottom of the queue. Hence, missing values are returned for the first n executions of LAGn, after which the lagged values of the argument begin to appear."
There can be issues of the wrong value being returned if you use conditional logic to invoke the LAG function, as illustrated in the example on returning every other value (that is shown in the doc).
In this instance experimenting with your actual data may be necessary. For example, in the data you show in your posting, when N=4, it is on the 4th row of data, so there are only 3 rows 'before' this row, therefore, there would be nothing (missing) for the lag4 function to return. In your example, on the N=4 row, the returned values for these invocations of the LAGn functions would be:
lag1 function would return 6
lag2 function would return 7
lag3 function would return 5
lag4 function would return .
input n p;
lval1 = lag(p);
lval2 = lag2(p);
lval3 = lag3(p);
lval4 = lag4(p);
if n = 1 then lval = lval1;
else if n = 2 then lval = lval2;
else if n = 3 then lval = lval3;
else if n = 4 then lval = lval4;
else if n = . then lval = .;
proc print data=uselag2;
var n p lval lval1-lval4;
i think you can use the code as follows
set yourdata point=j;
set yourdata point=i;
this is my idea to move the point by yourself, I haven't check the code, it may require some revise.