Определите структуру BASE при использовании PROC APPEND с пустой базой - PullRequest
0 голосов
/ 07 мая 2019

Я пытаюсь создать один набор данных с помощью итераций макро цикла. Я обнаружил, что для добавления в proc не требуется определенной BASE, поэтому подход должен быть жизнеспособным. Однако я столкнулся с проблемой с длинами имен переменных.

Я создал простой, воспроизводимый пример, который демонстрирует мою проблему. Конечно, это не самый эффективный способ создания моего окончательного набора данных want, но этот процесс имитирует рабочий процесс в моем коде.

proc sql;
    select name from sashelp.class;
    select name
        into :name_1 - :name_&sqlobs
    from sashelp.class;
quit;

%macro forward_loop;
%do i = 1 %to 10;
    proc sql;
    create table temp as
    select
    "&&name_&i" as name,
    age
    from sashelp.class
    quit;
    proc append base=want data=temp;
    run;
%end;
%mend;

%forward_loop;

ПРИМЕЧАНИЕ: добавление WORK.TEMP к WORK.WANT.

ВНИМАНИЕ: Имя переменной имеет разную длину в файлах BASE и DATA (BASE 6 DATA 7).

ОШИБКА: добавление не выполнено из-за перечисленных выше аномалий. Используйте опцию FORCE для добавления этих файлов.

ПРИМЕЧАНИЕ: добавлено 0 наблюдений.

Я полагаю, что могу решить эту проблему на этапе proc sql, просто указав, что name дополняется до определенной стандартной длины. Однако я не смог понять, как это сделать.

Это правильный подход? Или есть способ создать структуру BASE без каких-либо строк данных в BASE?

Ответы [ 3 ]

2 голосов
/ 07 мая 2019

Если вы создаете последовательно структурированные наборы данных, то тогда позволить PROC APPEND создать базовый набор данных из первого инкрементального набора данных будет работать нормально.

В вашем примере вы создаете NAME из строкового литерала, не указывая SAS, как долго делатьпеременная.Поэтому по умолчанию он будет создан до тех пор, пока строковый литерал.Если вы действительно используете этот метод в PROC SQL, добавьте атрибут LENGTH к определению столбца в вашем операторе SELECT.

"&&name_&i" as name length=8

Если вы действительно делаете это с шагом данных, то определите длину перед назначениемПеременное значение.

length name $8;
name = "&&name_&i";

Но может быть лучше сначала определить набор данных BASE перед входом в цикл.

data want;
  length name $8 age 8 ;
  stop;
run;
1 голос
/ 07 мая 2019

Трудно понять, соответствует ли ваш пример тому, что вы хотите сделать.

Определите ДЛИНУ имени в PROC SQL.

proc sql noprint;
    *select name from sashelp.class;
   select name into :name_1- from sashelp.class;
   quit;
%put _global_;

%macro forward_loop;
%do i = 1 %to 10;
   proc sql;
      create table temp_&i as
      select 
      "&&name_&i" as name length=8,
      age
      from sashelp.class
      quit;
   %end;
   %mend;
   options mprint=1;
   %forward_loop;

data want;
   if 0 then set sashelp.class(keep=name age);
   set temp_: open=defer;
   run;
1 голос
/ 07 мая 2019

Просто создайте набор данных с помощью шага данных. stop гарантирует, что наблюдения не будут записаны. Но вам также придется использовать FORCE, чтобы получить меньшие из них в наборе данных.

data want;
  length name $7;
  stop;
run;

Альтернативно создайте базовый набор данных таким же образом, но используйте метод вставки вместо proc append.

...