8. Array

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

8.1

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

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)>;

Рассмотрим, как можно использовать массив в нашей задаче:

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:

8.2

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

 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:

8.3

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

8.4

Где 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, которая удаляет значение переменной.

Полученный результат:

8.5

Для создания массива, в котором вам нужно описать временные элементы, можно использовать слово _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. С помощью цикла создаем символьные переменные (не забываем про проверку на пустые значения).

8.6

В полученном 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.

8.7.1
8.7.2 (продолжение data set)

Ссылки: