\documentclass[12pt]{article}
\usepackage[latin1]{inputenc}
\usepackage[brazil]{babel} 
\usepackage{Rd}

\newenvironment{codigo}[2]
{
  \begin{figure}[htb]
  \caption{#1}
  \label{#2}
  \begin{center}
  \begin{tabular}{|p{14cm}|}
  \hline
}{
  \\
  \hline
  \end{tabular}
  \end{center}
  \end{figure}
}

\title{Manipulação de Estruturas SEXP}
\author{Marcos Aurélio Carrero\\
Pedro Ribeiro de Andrade Neto\\
Paulo Justiniano Ribeiro Jr.}

\date{9 de julho de 2004}

\begin{document}
\maketitle

\section{Introdução}
Os objetos do \R{} são manipuladas no código C/C++ como uma estrutura de dados
chamada SEXP (\emph{Simple EXPression}). O \R{} disponibiliza dois arquivos de
cabeçalho contendo funções e macros para manipulação de estruturas SEXP, que 
são o \emph{Rdefines.h} e \emph{Rinternals.h}.

A estrutura SEXP consegue armazenar todos os dados processados pelo \R, como
listas, matrizes ou apenas um valor numérico. Mas o seu código está mal 
documentado, e quase não existe documentação complementar sobre a manipulação
desta estrutura de dados.

Este relatório tem como objetivo descrever os mecanismos necessários para 
construção e acesso de estruturas de dados SEXP. São apresentadas tanto as
funções disponibilizadas pelo \R{} quanto algumas implementadas pelos autores.

\section{Tipos de Dados}
Para os usuários das macros \emph{Rinternal.h}, é preciso saber qual o tipo de dado utilizado pelo SEXP, dos quais os mais utilizados estão ilustrados na tabela\ref{tab-r}:

\begin{table}[h]
  \begin{center}
    \begin{tabular}{|l|l|}
      \hline
      Tipo SEXP   &  Equivalente no \R\\
      \hline
      \hline
      REALSXP     &    numérico/double    \\
      \hline
      INTSXP      &    inteiro    \\
      \hline
      STRSXP      &    string    \\
      \hline
      VECSXP      &    lista(vetor genérico)    \\
      \hline 
      NILSXP      &    NULL    \\
      \hline
    \end{tabular}
    \vspace{0.2cm}
    \caption{Tipos de dados SEXP.}
    \label{tab-r}
  \end{center}
\end{table}

\section{Alocação de Memória}
Esta seção ilustra como alocar memória para a utilização de estruturas do R tais como vetores, matrizes e listas. Todas as estruturas são declaradas como sendo tipo SEXP, como segue:

\subsection{Manipulação de Vetores e Listas}
Para criar um novo vetor do tipo SEXP utiliza-se a macro allocVector, tendo como argumentos o tipo do dado e o seu tamanho, como ilustrado pela figura \ref{vetor}:\\

\begin{codigo}{Declaração de um SEXP como um vetor}{vetor}
\begin{verbatim}
SEXP obj = allocVector(INTSXP, 30);
\end{verbatim}
\end{codigo}

O SEXP \emph{obj} declarado acima é um vetor de inteiros com 30 posições. Na figura \ref{acesso_vetor} é mostrado como acessar uma posição do vetor:

\begin{codigo}{Acessando um elemento do vetor}{acesso_vetor}
\begin{verbatim}
int valor = INTEGER(obj)[0];
\end{verbatim}
\end{codigo}

Uma lista do tipo SEXP é um tipo particular de vetor, ou seja, um vetor de vetores. Para declarar uma nova lista utiliza-se a macro allocVector, no entanto o tipo do dado é um \emph{VECSXP}. 

\begin{codigo}{Declaração de um dado SEXP como lista}{exemplo}
\begin{verbatim}
SEXP obj = allocVector(VECSXP, 5);
SEXP intValor = allocVector(INTSXP, 2);
INTEGER(intValor)[0] = 10;
SET_VECTOR_ELT(obj, 0, intValor);
\end{verbatim}
\end{codigo}

O SEXP \emph{obj} declarado acima é uma lista contendo 20 posições e possui um elemento que é um vetor inteiro \emph{intValor}. A figura \ref{acesso_lista} mostra como acessar o primeiro elemento da lista:

\begin{codigo}{Acessando um elemento da lista}{acesso_lista}
\begin{verbatim}
SEXP elem = VECTOR_ELT(obj, 0);
\end{verbatim}
\end{codigo}

\subsection{Manipulação de matrizes}
Para declarar uma nova matriz utiliza-se a macro \texttt{allocMatrix}, que tem como argumentos o tipo do dado
SEXP, o número de linhas e o número de colunas, nesta ordem. A figura \ref{matriz} mostra um exemplo de declaração de matriz.

\begin{codigo}{Declaração de um dado SEXP como matriz}{matriz}
\begin{verbatim}
SEXP obj = allocMatrix(REALSXP, 10, 2)
\end{verbatim}
\end{codigo}

Quando um SEXP é declarado como matriz, o acesso aos dados é feito da mesma forma que o acesso a um vetor. No entanto ao acessar sequencialmente a matriz será percorrido sequencialmente as colunas da matriz. Para acessar uma posição da matriz utilizando-se como índice a linha e a coluna da matriz, pode-se utilizar a seguinte fórmula:
$linha + numero de linhas * coluna$. A figura \ref{acesso_matriz_i_j} mostra como acessar o elemento da linha zero, coluna zero da matriz \emph{obj} declarado na figura \ref{matriz}

\begin{codigo}{Acessando um elemento da matriz}{acesso_matriz_i_j}
\begin{verbatim}
double x = REAL(obj)[0 + 10 * 0];
\end{verbatim}
\end{codigo}

Para que este acesso pudesse ficar mais transparente, foi criada a macro \emph{MATRIX}, disponível em \emph{RUtils.h}, para encapsular o acesso à matriz. Dessa forma, utilizando-se a macro para acessar o elemento fica como ilustrado pela figura \ref{acesso_matriz_macro}

\begin{codigo}{Acessando um elemento da matriz}{acesso_matriz_macro}
\begin{verbatim}
int i = 0; int j = 0;
int row = nrows(obj);

double x = MATRIZ(obj, REAL, i, j, row);
\end{verbatim}
\end{codigo}

Para adicionar elementos à matriz pode-se utilizar a macro disponibilizada, como mostra  na figura \ref{matriz_seta_valor}.

\begin{codigo}{Adicionar elementos matriz}{matriz_seta_valor}
\begin{verbatim}
int row = nrows(obj);
int i = 0; int j = 0;
MATRIZ(obj, INTEGER, i, j, row) = 80;
\end{verbatim}
\end{codigo}

\section{Adicionando atributos às estruturas SEXP}
\subsection{Atributos de uma matriz}
Na figura \ref{matriz_attrib} é mostrado como adicionar o atributo \emph{dimnames}, que adiciona nomes às linhas e colunas de uma matriz.

\begin{codigo}{Adicinando atributos à uma matriz}{matriz_attrib}
\begin{verbatim}
SEXP obj = allocMatrix(REALSXP, 2, 4)

SEXP colnames = allocVector(STRSXP, 2);
SET_STRING_ELT(colnames, 0, mkChar("x"));
SET_STRING_ELT(colnames, 1, mkChar("y"));

SEXP rownames = allocVector(INTSXP, 4);
INTEGER(rownames)[0] = 0;

SEXP dimnames = allocVector(VECSXP, 2);
SET_VECTOR_ELT(dimnames, 0, colnames);
SET_VECTOR_ELT(dimnames, 1, rownames);

setAttrib(obj, R_DimNamesSymbol, dimnames);
\end{verbatim}
\end{codigo}

O SEXP \emph{dimnames} é uma lista que irá conter os vetores de atributos das linhas e colunas da matriz. O SEXP \emph{colnames} é um vetor contendo as strings \emph{x} e \emph{y} que contém o atributo da coluna. O SEXP \emph{rownames} contém valores inteiros usados nos atributos das linhas. A função \emph{setAttrib} é utilizada para adicionar o atributo à matriz.

\subsection{Atributos de uma lista}
Na figura \ref{lista_attrib} é mostrado como adicionar o atributo \emph{names} à uma lista. O tamanho do vetor do atributo \emph{names} deve ter o mesmo tamanho da lista.

\begin{codigo}{Adicionando atributos à uma lista}{lista_attrib}
\begin{verbatim}
SEXP obj = allocVector(VECSXP, 4);

SEXP names = allocVector(INTSXP, 4);
INTEGER(names)[0] = 0;

setAttrib(obj, R_NamesSymbol, names);
\end{verbatim}
\end{codigo}

\subsection{Acessando Tamanho e Tipo do dado SEXP}
Para verificar tamanho de um vetor, matriz ou lista utiliza-se a função \emph{length}, como mostrado na figura \ref{tamanho_geral}:

\begin{codigo}{Tamanho do SEXP}{tamanho_geral}
\begin{verbatim}
SEXP obj = ...;

int x = length(obj);
\end{verbatim}
\end{codigo}

Nesse exemplo \emph{x} contém o tamanho do SEXP \emph{obj}. Na figura \ref{tipo_geral} é mostrado como verificar qual o tipo de dado de um vetor. A mesma função poderia ser usada para verificar o tipo de uma matriz:

\begin{codigo}{Verificar o tipo do vetor}{tipo_geral}
\begin{verbatim}
SEXP names = allocVector(INTSXP, 4)
int tipo = isInteger(names);
\end{verbatim}
\end{codigo}
Nesse exemplo verificou-se se o SEXP \emph{names} é um vetor de inteiros. Existem outras funções tais como \emph{isReal}, \emph{isString} disponibilizadas em \emph{Rinternal.h}

No casa da lista, é preciso verificar o tipo de cada elemento. Na figura \ref{tipo_lista} é mostrado como acessar um elemento da lista:

\begin{codigo}{Verificar o tipo de um elemento do vetor}{tipo_lista}
\begin{verbatim}
SEXP obj = allocVector(VECSXP, 4);
SEXP vetor = allocVector(REALSXP, 2);
SET_VECTOR_ELT(obj, 0, vetor);

int tipo = isReal(VECTOR_ELT(obj, 0));
\end{verbatim}
\end{codigo}

Nesse exemplo verificou-se se o primeiro elemento do SEXP \emph{obj} é um vetor numérico.

\end{document}