\chapter{Серии и списки}
\label{chap:series-etc}

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

\section{Тип серии: \texttt{series}}
\label{sec:series}

Серии --- это то, что любой прикладной экономист назвал бы
«переменными», то есть повторяющиеся наблюдения в некотором заданном
количестве; набор данных --- это упорядоченный массив серий,
дополненный информацией, например, такой, как характер данных
(временной ряд, поперечное сечение или панель), описательные метки для
ряда и/или наблюдения, исходная информация и так далее.

Серии --- это базовый тип данных, от которого зависят все встроенные
оценочные команды gretl.  Серии, принадлежащие набору данных,
именуются стандартными идентификаторами Hansl (строки не более 31
символа, как описано выше). Что касается команд, которые используют
серии в качестве аргументов, они могут идентифицировать серии либо по
имени, либо по идентификатору, то есть по индексу серии в наборе
данных. Позиция 0 в наборе данных всегда является автоматической
«переменной», известной как const, которая представляет собой просто
столбец с единицами.

Идентификаторы фактических серий данных можно отобразить с помощью
команды \cmd{varlist}. (Но обратите внимание, что в функции вызова, в
отличие от команд, серии должны обозначаться только по имени.)
Подробное описание того, как работать с наборами данных, можно найти в
главе 4 Руководства пользователя Gretl.

Ниже приведены некоторые основные правила, касающиеся серий:

\begin{itemize}
\item Если \texttt{lngdp} принадлежит к временному ряду или набору
  данных панели, то синтаксис \texttt{lngdp(-1)} выдает первый лаг, а
  \texttt{lngdp(+1)} его первый лид.
\item Для доступа к отдельным элементам серии используйте квадратные
  скобки, заключающие что-то одно из следующего списка:
  \begin{itemize}
  \item прогрессивный (с 1) номер нужного вам наблюдения, как в
    \verb|lngdp[15]|
  \item соответствующий код даты в случае данных временного ряда, как
    в \verb|lngdp[2008:4]| (для 4-го квартала 2008 г.)
  \item соответствующую строку маркера наблюдения, если она есть в
    наборе данных, как например, \verb|GDP["USA"]|.
  \end{itemize}
\end{itemize}

Правила присвоения значений сериям такие же, как и для других
объектов, поэтому следующие примеры должно быть понятны:
\begin{code}
  series k = 3         # неявное преобразование из скаляра; постоянный ряд (серия)
  series x = normal()  # псевдо-rv через встроенную функцию
  series s = a/b       # поэлементная работа с существующими сериями

  series movavg = 0.5*(x + x(-1)) # с использованием лагов
  series y[2012:4] = x[2011:2]    # с использованием индивидуальных точек данных
  series x2000 = 100*x/x[2000:1]  # с построением индекса
\end{code}

\tip{В Hansl нет отдельных команд для создания и изменения
  серий. Другие популярные пакеты различают эти понятия, но мы все еще
  не нашли ответ, почему это различие может быть полезным.}

\subsection{Преобразование серий в матрицы и обратно}

Причина, по которой Hansl использует серии как отдельный и
определенный тип данных, отличный от матриц, уже ушла в историю. Тем
не менее, это тоже очень удобная функция. Операции, которые обычно
выполняются при помощи серий в прикладной работе, может быть неудобно
или сложно реализовать с использованием «сырых» матриц --- например,
вычисление опережения и запаздывания или регулярные и сезонные
различия; обработка пропущенных значений; добавление описательных
меток и т. д.

В любом случае, преобразовать данные в любом направлении между типами
серий и матриц не составит труда.

\begin{itemize}
\item Чтобы преобразовать ряды в матрицы, используйте синтаксис
  фигурных скобок, как в
  \begin{code}
    matrix MACRO = {outputgap, unemp, infl}
  \end{code}
  где также можно использовать списки; количество строк итоговой
  матрицы будет зависеть от вашей текущей выборки.
\item Чтобы превратить матрицы в серии, вы можете просто использовать
  столбцы матрицы, как в
  \begin{code}
    series y = my_matrix[,4]
  \end{code}
  Но имейте ввиду, что это сработает только в том случае, если
  количество строк в \texttt{my\_matrix} соответствует длине набора
  данных (или текущему диапазону выборки).
\end{itemize}
Также обратите внимание на то, что функции \cmd{lincomb} и
\cmd{filter} весьма полезны для создания серий и управления ими в
сложных случаях без необходимости преобразовывать данные в матричную
форму (что может быть накладно с точки зрения вычислений больших
наборов данных).

\subsection{Тернарный оператор с сериями}

Рассмотрим это задание:

\begin{code}
  worker_income = employed ? income : 0
\end{code}
Здесь мы предполагаем, что занятый \verb|employed| --- это фиктивный
ряд, кодирующий статус сотрудника. Его значение будет проверено при
каждом наблюдении в текущем диапазоне выборки и значение, присвоенное
\texttt{worker\_income} в этом наблюдении будет соответственно
определено. Следовательно, это же самое содержится в следующей более
подробной формулировке, где \dollar{t1} и \dollar{t2} --- аксессоры
для начала и конца диапазона выборки:

\begin{code}
series worker_income
loop i=$t1..$t2
    if employed[i]
        worker_income[i] = income[i]
    else
        worker_income[i] = 0
    endif
endloop
\end{code}

\section{Тип: список \texttt{list}}
\label{sec:lists}

На языке Hansl, список \textit{list} представляет собой массив целых
чисел, представляющих идентификационные номера набора серий. По этой
причине наиболее распространенные операции со списками --- это
операции с наборами серий, такие как добавление или удаление
элементов, объединение, пересечение и так далее. Однако, в отличие от
наборов, списки Hansl упорядочены, поэтому к отдельным членам списка
можно получить доступ через синтаксис \texttt{[]}, как в
\texttt{X[3]}.

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

\begin{code}
list xlist = 1 2 3 4
list reglist = income price 
\end{code}
Пустой список получается с помощью ключевого слова \texttt{null}, как
в
\begin{code}
list W = null  
\end{code}
или с помощью простого объявления. Еще несколько специальных форм
(например, с использованием подстановочных знаков) описаны в
Руководстве пользователя Gretl.

Основная идея состоит в том, чтобы использовать списки для группировки
под одним идентификатором одной или нескольких серий, которые
логически могут быть состыкованы вместе (например, в качестве
независимых переменных в модели). Так, например,

\begin{code}
list xlist = x1 x2 x3 x4
ols y 0 xlist
\end{code}
это способ определения регрессии OМНК, который также может быть
записан как
\begin{code}
ols y 0 x1 x2 x3 x4
\end{code}
Обратите внимание, что мы использовали здесь условие, упомянутое в
разделе \ref{sec:series}, согласно которому серию можно
идентифицировать по ID при использовании в качестве аргумента, если
ввести 0 вместо const.

Списки можно объединять, как в \texttt{list L3 = L1 L2} (где L1 и L2
--- имена существующих списков).  Однако это не обязательно то, что вы
хотите, поскольку полученный список может содержать дубликаты. Чаще
всего рекомендуется использовать следующие операции над наборами:

\begin{center}
  \begin{tabular}{rl}
    \textbf{Оператор} & \textbf{Значение} \\
    \hline
    \verb,||, & Объединение \\
    \verb|&&| & Пересечение \\
    \verb|-|  & Различие \\
    \hline
  \end{tabular}
\end{center}

Если \texttt{L1} и \texttt{L2} --- существующие списки, после
выполнения следующего фрагмента кода
\begin{code}
  list UL = L1 || L2 
  list IL = L1 && L2
  list DL = L1 - L2
\end{code}
список \texttt{UL} будет содержать все элементы \texttt{L1} плюс любые
элементы \texttt{L2}, которых еще нет в \texttt{L1}; \texttt{IL} будет
содержать все элементы, которые присутствуют как в L1, так и в L2, а
\texttt{DL} будет содержать все элементы L1, которых нет в L2.  Чтобы
добавить переменные к существующему списку, мы можем использовать
\textit{append} или \textit{prepend} и тот факт, что именованный
список создан пользователем «от руки». Например, предполагая, что
список \texttt{xlist} уже определен (возможно, как \texttt{null}), мы
сможем сделать следующее:

\begin{code}
list xlist = xlist 5 6 7
xlist = 9 10 xlist 11 12
\end{code}
Другой вариант для добавления или удаления условий из существующего
списка --- использовать \texttt{+=} или \texttt{-=}, соответственно,
как в

\begin{code}
xlist += cpi
zlist -= cpi
\end{code}
Хороший пример вышесказанного --- обычный скрипт: вы можете увидеть в
сценариях Hansl что-то вроде
\begin{code}
  list C -= const
  list C = const C
\end{code}
что гарантирует, что серия const будет включена (один раз) в список
\texttt{C} и будет первой.

\subsection{Преобразование списков в матрицы и обратно}

Как определено выше, идея преобразования из списка в матрицу может
быть реализована двумя способами. Вы можете превратить список в
матрицу (вектор), заполнив последнюю содержащимися в ней
идентификационными номерами из списка или же просто создаете матрицу,
столбцы которой содержат серии, на которые ссылаются
идентификаторы. Оба спобоса действенны (и потенциально полезны в
разных контекстах), поэтому Hansl позволяет вам действовать как
угодно.

Если вы назначите список матрице, как в

\begin{code}
  list L = moo foo boo zoo
  matrix A = L
\end{code}
матрица \texttt{A} будет содержать идентификационные номера четырех
серий в виде вектора-строки. Эта операция может быть осуществлена
обоими способами, так что заявление
\begin{code}
  list C = seq(7,10)
\end{code}
совершенно верно (при условии, конечно, что у вас есть не менее 10
серий в текущем открытом наборе данных).

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

\begin{code}
  matrix X = {L}
\end{code}

\subsection{Вариант цикла \texttt{foreach} со списками}

Списки могут использоваться в качестве «каталога» в варианте цикла
foreach (см. раздел \ref{sec:loop-foreach}). Это особенно удобно,
когда вам нужно выполнить какие-то операции с несколькими
сериями. Например, следующий синтаксис можно использовать для
вычисления и вывода среднего значения каждой из нескольких серий
\begin{code}
list X = age income experience
loop foreach i X
    printf "mean($i) = %g\n", mean($i)
endloop
\end{code}

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "hansl-primer"
%%% End: 
