Синтаксис last.order_id
подходит только в том случае, если на шаге DATA имеется оператор BY
- если он отсутствует, последний.ссылка всегда отсутствует и цикл никогда не закончится;Итак, вы закодировали бесконечный цикл!
Шаг имеет drop totalsales totalprofit _TYPE_ _FREQ_
.Эти подчеркнутые переменные указывают, что входящий набор данных, вероятно, был создан с Proc SUMMARY
.
В вашем наборе orders_fin_tot
должны быть столбцы order_id
quarter
(допустимые значения 1,2,3,4),и totalsales
.Если данные многолетние, в них должен быть еще один столбец с именем year
.
Отсутствующие BY
и присутствующие last.id
указывают, что вы преобразуете данные из категориального вектора, переходя от столбца к столбцу, которыйпроходит через ряд - это известно как поворот или транспонирование.Конструкция do
, которую вы показываете в вопросе, неверна, но похожа на технику, известную в кругах SAS как цикл DOW - особенность этой техники заключается в том, что SET
и BY
кодируются внутри цикл.
Попробуйте настроить код в соответствии со следующим шаблоном
data want;
do _n_ = 1 by 1 until (last.order_id);
SET work.orders_fin_tot; * <--- presumed to have data 'down' a column for each quarter of an order_id;
BY order_id; * <--- ensures data is sorted and makes automatic flag variable LAST.ORDER_ID available for the until test;
array QtrSales quarter1-quarter4 ; * <--- define array for step and creates four variables in the program data vector (PDV);
* this is where the pivot magic happens;
* the (presumed) quarter value (1,2,3,4) from data going down the input column becomes an
* index into an array connected to variables going across the PDV (the output row);
QtrSales{quarter} = totalsales;
end;
run;
Обратите внимание, что внутри или вне цикла нет оператора OUTPUT
.Когда цикл завершает свою итерацию, поток кода достигает нижней части шага данных и выполняет неявный OUTPUT (поскольку в другом месте шага нет явного OUTPUT).
Кроме того, для любого набора данных, указанного в коде,Вы можете использовать опцию набора данных OBS=
, чтобы выбрать, какие номера наблюдений будут использоваться.
proc print data=MyData(obs=10);
OBS
- сложное имя опции, потому что оно действительно означает последний номер наблюдения для использования .FIRSTOBS
- это еще одна опция набора данных для указания номеров строк, которые будут использоваться, и если их нет, по умолчанию используется 1
.Таким образом, вышесказанное эквивалентно
proc print data=MyData(firstobs=1 obs=10);
OBS = следует рассматривать концептуально как LASTOBS =;фактического названия опции LASTOBS нет.Следующее будет регистрировать ERROR:
, потому что OBS
proc print data=MyData(firstobs=10 obs=50);