Создание календаря в SAS

Вопрос или проблема

У меня есть этот код на R, который создает датафрейм календаря:

library(lubridate)
library(dplyr)

start_date <- ymd("2000-01-01")
end_date <- today()
date_seq <- seq(start_date, end_date, by = "day")

date_df <- data.frame(date = date_seq) %>%
  mutate(
    calendar_year = year(date),
    calendar_month = month(date),
    day = day(date),
    day_of_week = wday(date, label = TRUE, abbr = FALSE),
    fiscal_year = ifelse(month(date) >= 4,
                         paste0(year(date), "-", year(date) + 1),
                         paste0(year(date) - 1, "-", year(date))),
    fiscal_month = (month(date) - 3) %% 12 + 1,
    days_since_start_of_current_calendar_year = as.integer(date - floor_date(date, "year") + 1),
    days_since_start_of_current_fiscal_year = as.integer(date - floor_date(date %m+% months(3), "year") %m-% months(3) + 1)
  )

head(date_df)

Это выглядит так:

        date calendar_year calendar_month day day_of_week fiscal_year fiscal_month days_since_start_of_current_calendar_year days_since_start_of_current_fiscal_year
1 2000-01-01          2000              1   1    Saturday   1999-2000           11                                         1                                      93
2 2000-01-02          2000              1   2      Sunday   1999-2000           11                                         2                                      94
3 2000-01-03          2000              1   3      Monday   1999-2000           11                                         3                                      95
4 2000-01-04          2000              1   4     Tuesday   1999-2000           11                                         4                                      96
5 2000-01-05          2000              1   5   Wednesday   1999-2000           11                                         5                                      97
6 2000-01-06          2000              1   6    Thursday   1999-2000           11                                         6                                      98

Я задаюсь вопросом, может ли этот же код быть создан в SAS?

Я попытался перевести логику строчка за строчкой здесь:

data date_df;
    format date date9.;
    date="01JAN2000"d;
    do while (date <= today());
        calendar_year = year(date);
        calendar_month = month(date);
        day = day(date);
        day_of_week = put(date, downame.);
        
        if month(date) >= 4 then do;
            fiscal_year = put(year(date), 4.) || '-' || put(year(date) + 1, 4.);
        end;
        else do;
            fiscal_year = put(year(date) - 1, 4.) || '-' || put(year(date), 4.);
        end;
        
        fiscal_month = mod(month(date) - 3, 12) + 1;
        
        days_since_start_of_current_calendar_year = date - intnx('year', date, 0, 'B') + 1;
        days_since_start_of_current_fiscal_year = date - intnx('year', intnx('month', date, 3), 0, 'B') + 1;
        
        output;
        date = date + 1;
    end;
    
    drop date;
run;

proc sort data=date_df;
    by date;
run;

proc print data=date_df(obs=10);
run;

Можно ли использовать макросы SAS для этого? Или существует какой-то другой PROC, который можно использовать в SAS?

Ответ или решение

Создание календаря в SAS – это совершенно возможно и может быть выполнено с использованием ваших текущих знаний о программировании. Вы уже начали отлично переводить код R в код SAS, и я помогу вам завершить этот процесс.

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

Вот полное решение:

data date_df;
    /* Определяем формат для даты */
    format date date9.;

    /* Инициализируем дату 1 января 2000 года */
    date = '01JAN2000'd;

    /* Цикл для генерации дат до сегодняшнего дня */
    do while (date <= today());
        /* Вычисляем календарный год и месяц */
        calendar_year = year(date);
        calendar_month = month(date);
        /* Определяем день и день недели */
        day = day(date);
        day_of_week = put(date, downame.);

        /* Определяем финансовый год */
        if month(date) >= 4 then do;
            fiscal_year = put(year(date), 4.) || '-' || put(year(date) + 1, 4.);
        end;
        else do;
            fiscal_year = put(year(date) - 1, 4.) || '-' || put(year(date), 4.);
        end;

        /* Определяем финансовый месяц */
        fiscal_month = mod(month(date) - 3, 12) + 1;

        /* Количество дней с начала текущего календарного года */
        days_since_start_of_current_calendar_year = date - intnx('year', date, 0, 'B') + 1;

        /* Количество дней с начала текущего финансового года */
        days_since_start_of_current_fiscal_year = date - intnx('year', intnx('month', date, 3), 0, 'B') + 1;

        /* Выводим текущую строку в дата-сет */
        output;

        /* Увеличиваем дату на один день */
        date + 1;
    end;

    /* Удаляем временную переменную */
    drop date;

run;

/* Сортируем данные по дате */
proc sort data=date_df;
    by date;
run;

/* Печатаем первые 10 наблюдений для проверки результатов */
proc print data=date_df(obs=10);
run;

Объяснение кода

  1. Формат даты: Используем format date date9.; для отображения даты в стандартном формате.
  2. Инициализация даты: Устанавливаем начальную дату '01JAN2000'd;.
  3. Цикл do while: Этот цикл будет продолжаться до тех пор, пока дата меньше или равна сегодняшнему дню.
  4. Вычисления: Для каждого дня рассчитываются значения календарного года, месяца, дня, дня недели, финансового года, финансового месяца и количества дней с начала текущего календарного и финансового года.
  5. Вывод и кичка: Используем output для вывода строки данных для каждого дня, и увеличиваем дату на один день в конце итерации.
  6. Сортировка и печать: В конце сортируем полученные данные и печатаем первые десять записей для проверки.

Использование макросов

Использование макросов в SAS для этой задачи не обязательно, однако при необходимости автоматизировать процесс или генерировать календарь для разных диапазонов дат, макросы могут оказаться полезными. Например, вы можете создать макрос для установки начальной и конечной дат.

В итоге ваш скрипт создает календарь, аналогичный тому, который был создан в R, но с использованием функционала SAS. Если у вас есть дополнительные вопросы или нужно расширить функционал, не стесняйтесь спрашивать!

Оцените материал
Добавить комментарий

Капча загружается...