Frequência no R utilizando o pacote Hmisc

Como estou acostumado com o proc freq do SAS para validar algumas informações e ver se faz sentido o que estou fazendo, procurei algo semelhante no R. Encontrei o describe() do pacote Hmisc. Claro que deve existir outro pacote que faz isso, mas esse foi o primeiro que encontrei.

O proc freq do SAS, como o nome já indica, calcula a frequência de seus dados. Por exemplo, se você tem uma base que contém homem e mulher, você pode utilizar um código parecido com esse:

proc freq data = base_de_dados; table sexo; run;

Onde base_de_dados seria o nome da sua base e sexo o nome da coluna contendo o sexo das pessoas.Esse código retorna para você o número e a porcentagem de pessoas de cada sexo. Analogamente, você poderia fazer o seguinte código no R:

install.packages("Hmisc");
library("Hmisc");
describe(base_de_dados$sexo);

E o resultado seria o mesmo.

Para não ficar muito abstrato, segue um exemplo com a base de dados german_credit_21 já utilizada no post Árvore de Decisão no R. Eu tinha discretizado algumas variáveis naquela época, e estava refazendo isso hoje. Apenas para garantir que tinha feito da forma correta, utilizei o describe(). Veja que ele me retornou que 30% da minha base possui Creditability ‘bad’ e 70% ‘good’. Além disso, pude ver também como foi dividido o CreditAmount. Bem simples, uma função só e você já tem uma bela descrição para trabalhar:

install.packages("Hmisc");
library("Hmisc");
describe(dados);

 

Macros e a expressão Let no SAS

No post As boas práticas de programação foi mencionado que o código deveria ser o menos estático possível? No SAS isso pode ser feito muito bem com a criação de Macros e com a expressão %LET.

CONCEITO DE MACROS

De acordo com o Wikipedia “Uma macro (abreviação para macroinstrução), em ciência da computação, é uma regra ou padrão que especifica como uma certa sequência de entrada (frequentemente uma sequência de caracteres) deve ser mapeada para uma substituição de sequência de saída (também frequentemente uma sequência de caracteres) de acordo com um procedimento definido.”

Ou seja, uma macroinstrução é uma sequência de regras que o programa deve seguir. Quando você cria uma macro, você cria um programinha que vai executar uma série de procedimentos.

MACROS NO SAS

No SAS, assim como em outros programas, você pode deixar uma série de nomes flexíveis dentro da sua sequência de procedimentos, para que eles rodem diversas vezes soltando saídas diferentes.

Por exemplo, suponha que a gente tenha a base FATURA_YYYYMM gerada mensalmente com as faturas dos clientes no mês corrente. Você está realizando um estudo com clientes que possuem faturas de valor acima de R$ 200,00. Porém, para seu estudo, você vai pegar clientes dos primeiros três meses do ano. Se a pessoa não conhece muito sobre macros, é esperado que ela faça um código como esse:

data faturas_jan;
     set fatura_201601;
     if vlr_fatura > 200;
run;

data faturas_fev;
     set fatura_201602;
     if vlr_fatura > 200;
run;

data faturas_mar;
     set fatura_201603;
     if vlr_fatura > 200;
run;

Não parece a melhor maneira. Alguém mais calejado já estaria quebrando a cabeça imaginando que existe um jeito mais prático. Existe, é utilizando as macros do SAS.

No começo parece até algo mais complicado, mas é bem simples. A sintaxe é da seguinte forma:

%macro nome_da_macro(input 1, input2, ...);
     comando 1;
     comando 2;
     .
     .
     .
%mend;
%nomedamacro(input 1, input2, ...);

Sendo assim, podemos criar a macro EXTRAI_FATURA na qual vamos colocar como inputs os nomes das bases que serão lidas e como output as bases de saída:

%macro extrai_fatura(input, output);
data &input;
     set &output;
     if fatura > 200;
run;
%mend;

%extrai_fatura(fatura_201601, extracao_janeiro);
%extrai_fatura(fatura_201602, extracao_fevereiro);
%extrai_fatura(fatura_201603, extracao_marco);

Veja que a macro está lendo as bases que declaramos como input e está soltando os resultados em bases com o nome que passamos como output (extracao + nome do mês).

Note que precisamos colocar o caractere ‘&’ antes do nome das variáveis que serão substituídas. Note também, que a macro pode ficar ainda mais flexível com você passando o valor que quiser em cada extração:

%macro extrai_fatura(input, output, valor);
data &input;
     set &output;
     if fatura > &valor;
run;
%mend;

%extrai_fatura(fatura_201601, extracao_janeiro, 100);
%extrai_fatura(fatura_201602, extracao_fevereiro, 200);
%extrai_fatura(fatura_201603, extracao_marco, 300);

Nessa segunda macro, podemos colocar o valor que quisermos em cada extração. A primeira execução vai ler a fatura_201601 e retornar a extracao_janeiro apenas com clientes que possuem fatura acima de R$ 100,00. A segunda execução lê a fatura_201602 e retorna a extracao_fevereiro apenas com os clientes de fatura acima de R$ 200,00.

%LET NO SAS

A expressão %LET é mais fácil ainda que a macro, embora não ache ela tão poderosa.

Essa expressão também serve para alterar parâmetros no meio do seu código, porém, diferentemente da macro, você declara a variável uma vez no início do código. Uma das facilidades que eu vejo no LET é que permite você rodar o código por partes, o que facilita bastante para pegar erros. Facilita para processos executados periodicamente em que se altera algumas variáveis de inputs. Vamos supor que agora você não vai fazer um estudo, mas você quer fazer uma campanha com os clientes de alta renda e todo mês, assim que a base de faturamento for gerada, você vai pegar os clientes que possuem faturas acima de R$ 500,00. Você faria o seguinte código no mês de janeiro:

%let base_fatura = fatura_201601;
data extracao_campanha;
     set &base_fatura;
     if fatura > 500;
run;

Novamente, a gente declara uma variável e insere ela no código com o comando ‘&’ seguido do nome do input. No mês seguinte, você precisaria apenas trocar o valor atribuído ao %let e executar o mesmo código:

%let base_fatura = fatura_201602;
data extracao_campanha;
     set &base_fatura;
     if fatura > 500;
run;

Pense agora na quantidade de possibilidades. Deixar o valor da fatura, o nome da base de saída e outras variáveis flexíveis também. Pense agora se você tivesse 50 condições ao invés dessa única. Facilitaria bastante, não?

Dica rápida: Acrescentando zero na frente do número no SAS

Sabe aquele cpf que algum sem noção mandou em formato numérico e veio com menos de 11 dígitos na sua base?

Para deixá-lo com 11 dígitos e com zero na frente é simples, use o put() e o ‘z11.’ na sequência.

Por exemplo, você recebeu a tabela Clientes, na qual a coluna DOCUMENTO veio em formato numérico, ou seja, muitos não vão ter 11 dígitos, e você pode querer o CPF correto por diversos motivos. A conversão é simples, você utiliza um length apenas para garantir o comprimento da variável correto e manda bala no put:

data clientes_v2;
    set clientes;
    length cpf $11.;
    cpf = put(documento, z11.);
run;

Excluindo colunas no R

Uma dica rápida, mas que ajuda bastante.

Vamos supor que você tenha uma tabela com 7 colunas, e você queira excluir algumas colunas dela para sua análise. Como você faz?

Simples, utiliza o c() e coloca o sinal de negativo antes do número da coluna que você quer excluir. Como exemplo, temos a seguinte tabela com o preço médio dos combustíveis no Brasil, levantado pela ANP:

Veja que a primeira coluna é uma data e a última possui diversos NAs, o que atrapalha diversas operações.

Se você tentar utilizar a função log(), por exemplo, você vai ter um erro:

log(ANP_COMBUSTIVEIS[,c(-1,-7)])
PRECO_REV_ETANOL PRECO_REV_GASOLINA PRECO_REV_GLP PRECO_REV_GNV PRECO_REV_DIESEL
1 0.009257021 0.5196268 2.844613 -0.31471074 -0.18717331
2 0.014198719 0.5370780 2.873706 -0.29988962 -0.16251893
3 0.026154957 0.5411608 2.884778 -0.30042965 -0.15059036
4 0.038354954 0.5758828 2.930244 -0.26748737 -0.10725119
5 0.032079893 0.5767257 2.937520 -0.24910259 -0.09695153
6 0.028490270 0.5736314 2.928181 -0.24718013 -0.09673119
7 0.018821754 0.4621605 3.084173 -0.24654013 -0.12386399

Agora, se você utilizar c(-1,-7) na posição da coluna na matriz, você consegue seu resultado sem problema:

log(ANP_COMBUSTIVEIS[,c(-1,-7)])
 PRECO_REV_ETANOL PRECO_REV_GASOLINA PRECO_REV_GLP PRECO_REV_GNV PRECO_REV_DIESEL

1 0.009257021 0.5196268 2.844613 -0.31471074 -0.18717331
2 0.014198719 0.5370780 2.873706 -0.29988962 -0.16251893
3 0.026154957 0.5411608 2.884778 -0.30042965 -0.15059036
4 0.038354954 0.5758828 2.930244 -0.26748737 -0.10725119
5 0.032079893 0.5767257 2.937520 -0.24910259 -0.09695153
6 0.028490270 0.5736314 2.928181 -0.24718013 -0.09673119
7 0.018821754 0.4621605 3.084173 -0.24654013 -0.12386399

Veja o que acontece se você der um View(ANP_COMBUSTIVEIS[,c(-1,-7)]:

Se você quiser excluir da coluna 1 até a coluna 5, você pode simplesmente fazer ANP_COMBUSTIVEIS[,c(-1:-5)], afinal:

c(-1:-5)
[1] -1 -2 -3 -4 -5

Evitando “NA” nos cálculos do R

É sempre um problema trabalhar com NAs no R. Veja o código abaixo, onde foi criada uma matriz 2×2 contendo um elemento NA:

matriz_teste = array(data=c(10,NA,5,2), dim=c(2,2));
matriz_teste;

Para calcular a média das colunas, deveríamos utilizar a função colMeans() do R, mas veja que a sintaxe abaixo retorna um erro:

colMeans(matriz_teste);

O R não consegue calcular a média por causa desse NA. Porém, o R é muito inteligente, e para calcular a média quando tiver um NA no caminho, você não precisa de muito esforço, basta acrescentar o  argumento na.rm = TRUE:

colMeans(matriz_teste, na.rm = TRUE);

Veja que ele simplesmente ignora o elemento NA. É como se houvesse apenas um elemento na coluna. Se a coluna tivesse quatro elementos, sendo que dois eram NAs, a média seria calculada como a soma dos dois elementos não NAs dividida por dois.

E isso funciona também para a função que calcula a soma da coluna:

colSums(matriz_teste, na.rm = TRUE)

Simples, não?

Com relação a função chamada array(), leia o conteúdo do Wikipedia sobre arranjo.