Рассмотрим data set TEMP, в котором хранится информация про температуру тела каждого пациента на визитах 1-5 (переменные vis1 - vis5). Нужно конвертировать значение температуры из градусов по Фаренгейту в градусы Цельсия с точностью до одного знака.

Не забывая о проверке на пустые значение, эту задачу можно решить следующем образом:
data Temp_C; set Temp; if ~missing(vis1) then vis1=round((vis1-32)*5/9,.1); if ~missing(vis2) then vis2=round((vis2-32)*5/9,.1); if ~missing(vis3) then vis3=round((vis3-32)*5/9,.1); if ~missing(vis4) then vis4=round((vis4-32)*5/9,.1); if ~missing(vis5) then vis5=round((vis5-32)*5/9,.1); run;
Можно увидеть, что для реализации этой задачи мы используем одни и те же операции, но для разных переменных. Модифицировать это решение можно с помощью массива.
Синтаксис:
ARRAY array-name { subscript } <$> <length> <array-elements> <(initial-value-list)>;
- array-name – имя массива (SAS имя массива не должно совпадать с именем любой переменной, которая уже имеется на этом шаге данных);
-
subscript - количество или диапазон элементов массива (можно использовать любые скобки : (…), {…}, […]):
- { 4 } - массив состоит из 4 переменных;
- { * } - в этом случае SAS сам определяет количество элементов в заданном массиве;
- $ - указывает на то, что все элементы массива символьные (если этот знак отсутствует – все элементы массива числовые);
- length – длина каждого элемента массива (на случай, если вы не инициализировали длину до этого);
- array-elements – указывает на имена переменных (уже существующих на данном шаге данных), составляющих массив. Все элементы массива должны быть одного типа: либо числовые, либо символьные. Также они могут быть перечислены в любом порядке.
Варианты определения элементов массива:
-
array variable {5} var1 – var5;
(variable{1}=var1, variable{2}=var2 и т.д.)
-
array vital_signs {3} weight height BMI;
(vital_signs {1}= weight, vital_signs {2}= height, vital_signs {3}= BMI)
-
array days{7};
(создает пустые переменные days1, days2, days3 и т.д.)
-
array x{*} _NUMERIC_;
(создает массив из всех числовых переменных на шаге данных)
-
array x{*} _CHARACTER_;
(создает массив из всех символьных переменных на шаге данных)
-
array x{*} _ALL_;
(создает массив из всех переменных на шаге данных)
-
array variable {5} var1 – var5;
(variable{1}=var1, variable{2}=var2 и т.д.)
- initial-value-list – присваивание начальных значений для элементов массива (Например: array vital_signs {3} weight height BMI (55, 163, 20.7) или array variable {4} ('value 1' ' value 2' ' value 3' ' value 4') ). Если элементов массива больше, чем начальных значений, остальным элементам массива присваиваются пустые значения, и SAS выводит предупреждение. Элементы массива хранят начальные значение до тех пор, пока значение элемента не будет изменено.
Рассмотрим, как можно использовать массив в нашей задаче:
data Temp_C2(drop=i); set Temp; array celsius {5} vis1-vis5; do i=1 to 5; if ~missing(celsius{i}) then celsius{i}=round((celsius{i}-32)*5/9, .1); end; run;
Шаг 1. Массив должен быть объявлен до того, как осуществляется ссылка на имя массива (операции над элементами массива).
Шаг 2. Имя массива не должно совпадать с именем любой переменной, которая уже есть в data set Temp.
Шаг 3. Используем цикл для обработки каждого элемента массива. Для этого нужно указать диапазон значений индексной переменной і от 1 до количества элементов массива.
Полученный дата сет Temp_C2:

Для того, чтобы создать новые переменные, в которых будет храниться конвертированная температура в соответствии каждому визиту, удобно воспользоваться еще одним массивом:
data Temp_C3(drop=i); set Temp; array F_temp {5} vis1-vis5; array C_temp {5} vis_c1-vis_c5; do i=1 to 5; if ~missing(F_temp{i}) then C_temp{i}=round((F_temp{i}-32)*5/9, .1); end; run;
Полученный data set Temp_C3:

Рассмотрим data set Raw_vs:

Где HEIGHT, WEIGHT, BMI, SBP, DBP, PRATE, TEMP – числовые переменные. Требуется заполнить пропусками все чиловые переменные, значение которых равно 9999.
data VS_result(drop=i); set Raw_vs; array num_var{*} _numeric_; do i=1 to dim(num_var); if num_var(i)=9999 then call missing(num_var(i)); end; run;
Шаг 1. Объявляем массив неизвестной длины (для этого указываем * в скобках), и, так как нам нужно заменить значения во всех числовых переменных, пользуемся значением _numeric_ .
Шаг 2. Используем цикл. Так как количество элементов массива не указано, используем функцию dim (Синтаксис: DIM(array-name).
Шаг 3. С помощью сравнения находим значения, где переменные равны 9999 , и вызываем функцию call missing, которая удаляет значение переменной.
Полученный результат:

Для создания массива, в котором вам нужно описать временные элементы, можно использовать слово _TEMPORARY_ вместо указания имен переменных. Временные элементы не выводятся в выходной набор данных.
Рассмотрим следующую задачу: для предыдущего data set VS_result создать символьные переменные HEIGHTС, WEIGHTС и т.д., в которых будет храниться значение соответствующих переменных и единицы измерения для каждой переменной (HEIGHT - cm, WEIGHT - kg, BMI - kg/m2 , SBP - mmHg, DBP - mmHg, PRATE - BEATS/MIN, TEMP - F):
data VS_unit(drop=i); set VS_result; array num_var{*} HEIGHT WEIGHT BMI SBP DBP PRATE TEMP ; array unit{7} $ _TEMPORARY_("cm","kg","kg/m2","mmHg","mmHg","BEATS/MIN","F"); array char_var {*} $ 20 HEIGHTC WEIGHTC BMIC SBPC DBPC PRATEC TEMPC; do i=1 to dim(num_var); if ~missing(num_var(i)) then char_var(i)=strip(put(num_var(i), best.))||" "||unit(i); end; run;
Шаг 1. Объявляем массив переменных num_var, значение которых мы будем использовать для создания новых переменных;
Шаг 2. Объявляем временный массив для юнитов (соблюдаем порядок, который соответствует порядку переменных в массиве num_var);
Шаг 3. Объявляем массив символьных переменных, длина которых равна 20;
Шаг 4. С помощью цикла создаем символьные переменные (не забываем про проверку на пустые значения).

В полученном data set можно увидеть, что элементы временного массива не сохраняются в data set VS_unit, а только используются для создания новых переменных.
Вращение SAS набора данных
С помощью обработки массива можно выполнить вращение (транспонирование) набора данных. Пользуясь этим, транспонируем data set VS_unit:
data VS_transp; set VS_unit; array num_var{*} HEIGHT WEIGHT BMI SBP DBP PRATE TEMP ; array vs_test {7} $ _TEMPORARY_('HEIGHT' 'WEIGHT' 'BMI' 'SBP' 'DBP' 'PRATE' 'TEMP'); do i=1 to dim(num_var); VSTEST=vs_test(i); VSORRES=num_var(i); output; end; keep Subject VSTEST VSORRES; run;
Шаг 1. Объявляем массив переменных num_var, значение которых мы будем использовать для транспонирования и сохраняем в переменную VSORRES;
Шаг 2. Объявляем массив временных переменных vs_test. В том же порядке, в котором объявили элементы массива num_var, присваиваем начальные значения, которые будут использоваться для переменной VSTEST;
Шаг 3. С помощью цикла присваиваем переменным VSTEST и VSORRES значения массивов. Пользуемся оператором output для вывода каждого элемента массива на новую строку;
Шаг 4. Сохраняем в data set только переменные Subject VSTEST VSORRES.


Ссылки: