2013-03-17 4 views
2

у меня есть набор данные SAS, которая имеет 20 переменные символы, все из которых являются имена (например, Адам, Боб, Cathy и т.д ..)SAS - Создание переменных из макропеременных

Я хотел бы динамический код для создания переменных называется Adam_ref, Bob_ref ​​и т. д., который будет работать, даже если есть другой набор данных с разными именами (т. е. не нужно вручную определять каждую переменную).

До сих пор мой подход в том, чтобы использовать содержимое Proc, чтобы получить все имена переменных, а затем использовать макрос для создания макропеременные Adam_ref, Bob_ref ​​и т.д ..

Как создать фактические переменные в наборе данных здесь? Нужен ли мне другой подход?

proc contents data=work.names 
       out=contents noprint; 
run; 

proc sort data = contents; by varnum; run; 

data contents1; 
    set contents; 
    Name_Ref = compress(Name||"_Ref"); 
    call symput (NAME, NAME_Ref); 
    %put _user_; 
run; 

ответ

1

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

Сохраните значения в макропеременные, которые названы по некоторому шаблону, как v1, v2 ...

proc sql; 
select compress(Name||"_Ref") into :v1-:v20 from contents; 
quit; 

Если вы не знаете, сколько значений есть, вы должны считать их первыми, Я предположил, что их всего 20.

Тогда, если все переменные являются символьные переменные длины 100, вы создаете набор данных, как это:

%macro create_dataset; 
data want; 
length %do i=1 %to 20; &&v&i $100 %end; 
; 
stop; 
run; 
%mend; 

%create_dataset; run; 

Это, как вы можете это сделать, если у вас есть значения в макропеременной, есть, вероятно, лучший способ сделать это в целом.

Если вы не хотите, чтобы создать пустой набор данных, но только изменить имена переменных, вы можете сделать это следующим образом:

proc sql; 
select name into :v1-:v20 from contents; 
quit; 

%macro rename_dataset; 
data new_names; 
set have(rename=(%do i=1 %to 20; &&v&i = &&v&i.._ref %end;)); 
run; 
%mend; 

%rename_dataset; run; 
1

Вы можете использовать PROC TRANSPOSE с ID заявление.

Этот шаг создает пример набора данных:

data names; 
    harry="sally"; 
    dick="gordon"; 
    joe="schmoe"; 
run; 

Этот шаг, по существу, копия вашего шага выше, что создает набор данных имен столбцов. Я буду повторно использовать набор данных.

proc contents data=names out=namerefs noprint; 
run; 

Этот шаг добавляет «_Refs» к именам, определенным ранее, и отбрасывает все остальное. Переменная «name» происходит от атрибутов столбца вывода набора данных с помощью PROC CONTENTS.

data namerefs; 
    set namerefs (keep=name); 
    name=compress(name||"_Ref"); 
run; 

На этом этапе создается пустой набор данных с нужными столбцами. Переменная «name» снова получается путем просмотра атрибутов столбца. Если вы попытаетесь просмотреть набор данных, вы можете получить безобидное предупреждение в графическом интерфейсе, но в противном случае вы можете использовать его по своему усмотрению, и вы можете подтвердить, что он имеет желаемый результат.

proc transpose out=namerefs(drop=_name_) data=namerefs; 
    id name; 
run; 
1

Вот еще один подход, который требует меньше кодирования. Он не требует запуска содержимого proc, не требует знания количества переменных и создания макрофункции. Это также можно расширить, чтобы сделать некоторые дополнительные вещи.

Шаг 1 - использовать встроенные словарные представления для получения имен переменных. Соответствующим представлением для этого является словарь. Columns, который имеет псевдоним sashelp.vcolumn. Словарь libref может использоваться только в proc sql, а псевдоним sashelp можно использовать в любом месте. Я использую sashelp alias, поскольку я работаю в Windows с DMS и всегда могу интерактивно просматривать библиотеку sashelp.

proc sql; 
    select compress(Name||"_Ref") into :name_list 
           separated by ' ' 
    from sashelp.vcolumn 
    where libname = 'WORK' 
    and memname = 'NAMES'; 
quit; 

Это создает макрос, ограниченный пробелом, с желаемыми именами.

Шаг 2 Для создания пустого набора данных, то этот код будет работать:

Data New ; 
    length &name_list ; 
run ; 

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

Например

select compress(Name)||"_Ref $")||compress(put(length,best.)) 
       into :name_list 
       separated by ' ' 

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

Для создания густонаселенных набора данных для использования с опцией переименования набора данных, замените оператор выбора следующим образом:

select compress(Name)||"= "||compress(_Ref") 
        into :name_list 
        separated by ' ' 

Затем замените код Шага 2 следующим:

Data New ; 
    set names (rename = (&name_list)) ; 
run ;