Soma com condição no SAS: Agrupamentos com Proc Sql

O group by é um método bem tranquilo de agrupar os valores de uma coluna de acordo com os valores de outra coluna. Veja os três exemplos abaixo, onde queremos primeiro saber qual o número de vendas de cada marca, o número de vendas por estado e o número de vendas de cada marca em cada estado:

Leia mais…

Acompanhando a execução da macro no SAS

Mostrei no post Acompanhando o processo no SAS utilizando o Sysecho como utilizar o comando sysecho para acompanhar um procedimento extenso, algo que leva muito tempo para ser executado ou com muitas etapas. Porém, seria interessante também fazer um acompanhamento parecido quando executamos uma macro.

Leia mais…

Convertendo diferentes formatos de data no SAS

Essa é intuitiva, mas não sei se todo mundo conhece. Então, se você leu Como calcular a diferença entre duas datas no SAS? e Formatando Datas no SAS, agora que já conseguiu criar colunas e mudar formato numérico para data, pode ainda querer trocar aquela data 20DEC2016 para 20/12/2016. Isso pode ser feito com o format:
*codigo que pega a tabela_old, com o campo data no formato 20DEC2016;
*e cria uma tabela nova chamada tabela_new com a data no formato 20/12/2016;
data tabela_new;
	set tabela_old;
 	format data ddmmyy10.;
run;

SAS: Executando diversos códigos em um só com o include

Assim como é possível chamar outros códigos no R e utilizar algumas funções prontas, no SAS algo semelhante pode ser feito declarando INCLUDE.

Quando você utiliza o include seguido de um caminho com um programa SAS, o que vai acontecer é que esse programa será executado. Sendo assim, você pode rodar diversos códigos em um projeto só, pode consolidar as suas libnames em um lugar só, enfim, há várias alternativas, todas com o include.

Uma situação hipotética: sua empresa possui uma base padrão, dentro de um DW qualquer, com um campo de data no formato string “ddmmaaaa”. Vamos supor que você tenha criado um projeto no qual um dos programas seja uma macro, denominada trata_data, que recebe a base padrão e converte o campo string para o formato data padrão do SAS. Você utilizou essa macro nesse projeto, mas ela é pode ser útil em vários outros estudos. O que você pode fazer é salvar essa macro como um programa em um diretório e quando você precisar utilizá-la em outro código, você utilizará algo como a sintaxe:

*chama a macro que tratara a data da base padrao (base_in) 
*e gera uma base com campo tratado (base_out);
%include '/sasdata/minhaempresa/macro_trata_data.sas';
%trata_data(base_in, base_out);

Outra forma de utilizar o include é na automatização de alguns processos. Vamos supor que você tenha criado um modelo estatístico que gera o rating das empresas clientes do seu banco e você deseja automatizar o processo de geração de rating para várias bases diferentes que chegarão mensalmente. Para isso, você pode criar diversos programas que receberão algumas variáveis, como a base de entrada e uma base de cadastro que enriquecerá a base de entrada, e rodá-los todos com o include. O exemplo abaixo pressupõe um programa chamado gera_rating_empresa.sas e dentro desse programa você possui duas variáveis/bases que devem ser passadas pelo usuário chamadas base_in e base_endereco (lembre-se que no programa elas precisam ser chamadas com &base_in e &base_endereco):

*insira o nome da base de entrada com campo CNPJ com 14 dígitos (string);
%let base_in = base_entrada_yyyymmdd;

*passe a base que enriquecera com as informacoes de endereco;
%let base_endereco = base_endereco_yyyymmdd;

*execute o programa;
%include "/sasdata/.../gera_rating_empresa.sas";

Não se esqueça de ficar craque em macros / let: Macros e a expressão Let no SAS

Combinando três tabelas com o left join

Utilizando as informações do post Como combinar tabelas no SAS utilizando left join e full join, vamos imaginar que não tenhamos apenas duas tabelas, mas sim três, sendo que a terceira tabela contém as notas dos alunos que cursam Física:
Para montar uma única query que traga a nota de física, basta continuar o left join:
* notas dos alunos de calculo incluindo as de fisica dos que fizeram;
proc sql;
    create table exemplo_left_join as
    select a.*, b.nota_estat, c.nota_fis
        from turma_calc as a
          left join (select * from turma_estat ) as b
          on a.nome = b.nome
            left join (select * from turma_fis) as c
            on a.nome= c.nome;
run;
E você poderia inclusive filtrar antes de aplicar o left join. Como?
Bem, para quem leu o post SQL dentro do SAS sobre SQL fica bem claro o que foi feito acima: foi aplicado um left join em uma base construída entre parênteses. Ou seja, se para extrair as informações da turma de Física usamos select * from turma_fis, pra extrair os alunos aprovados na disciplina bastaria utilizar select * from turma_fis where Nota_Fis >= 6, teríamos então:
* excluindo os alunos reprovados em fisica;
proc sql;
    create table exemplo_left_join_2 as
    select a.*, b.nota_estat, c.nota_fis
    from turma_calc as a
    left join (select * from turma_estat ) as b
      on a.nome = b.nome
    left join (select * from turma_fis where Nota_Fis >= 6) as c
      on a.nome= c.nome;
run;
Agora que você sabe extrair informações utilizando o SQL e sabe que você pode fazer o que quiser dentro do parênteses antes de aplicar o left join, você poderia inclusive ser mais ousado e criar uma marcação de alunos aprovados, onde o campo Aprovado receberia 1 quando o aluno tem nota superior ou igual a 6 e 0 caso contrário:
* cria uma flag = 1 para trazer quem foi aprovado em fisica e estatistica;
proc sql;
    create table exemplo_left_join_3 as
    select a.*, b.Aprovado_Estat, c.Aprovado_Fis
    from turma_calc as a
    left join (
            select *, case when Nota_Estat >= 6 then 1
            else 0 end as Aprovado_Estat from turma_estat ) as b
      on a.nome = b.nome
    left join (
             select *, case when Nota_Fis >= 6 then 1
             else 0 end as Aprovado_Fis from turma_fis) as c
      on a.nome= c.nome;
run;

Trabalhando com espaços e acentos no SAS

A pior coisa é utilizar campos com espaços em branco e acentos quando se está programando. Não é recomendável e muitas vezes resulta em erros. Porém, às vezes temos que lidar com isso porque alguém construiu uma base com campos dessa forma e não quer mudar.

No SAS é mais fácil lidar com isso, basta acrescentar aspas e a letra n. É bem semelhante quando você utiliza data, só que precisa trocar o ‘d’ por ‘n’.

Vamos supor que você receba os dados da turma de alunos do post Visualizando seus dados: histograma e queira criar uma marcação chamada Reprovação que receberá o número 1 para alunos que tiraram notas menor que 6, basta você criar o campo ‘Reprovação’n:

data dados_v2;
    set dados;
    if notas < 6 then 'Reprovação'n = 1;
    else 'Reprovação'n = 0;
run;

Poderíamos também cair em uma situação que seria necessário criar um campo Data de Atualização com a data do dia de hoje. Para isso, temos duas opções:

## primeira opcao:
data dados_v2;
    set dados;
    'Data de Atualização'n = today();
run;

## segunda opcao:
data dados_v2;
    set dados;
    'Data de Atualização'n = '13JUL2016'd;
run;

Contador e função oposta ao lag no SAS

Veja que exercício de lógica interessante:

Pense em uma base com clientes que possuem vários carros. Você tem linhas contendo o nome do cliente, o nome do carro que ele possui e a data de compra do veículo. Você precisa descobrir quais clientes possuem apenas um carro. A que eu vou demonstrar talvez não seja a mais eficiente, até porque eu precisei de alguns dados ao longo do estudo, como por exemplo qual a ordem em que o veículo foi comprado. Sem isso, não sei se eu teria pensado de outra forma. O legal da forma que foi feito o tratamento é que trabalha o raciocínio lógico e ainda apresenta alguns algoritmos úteis.

O passo a passo utilizado é o seguinte: ordene seus dados pelo nome e data de compra do veículo; crie um contador para representar se é o primeiro carro que aparece do cliente; crie uma coluna adicional para saber qual o contador da linha seguinte. Veja que se você tiver na linha 10 o valor 1 no contador, e na linha 11 você tiver o valor 2, é sinal de que o cliente possui pelo menos dois veículos. No entanto, se você tiver o valor 1 no contador da linha 10 e o valor 1 no contador da linha 11, o seu cliente da linha 10 possui apenas 1 carro.

Foi falado um pouco sobra a função lag() do SAS no post Média Móvel (Bônus: Código SAS e função lag). Ela simplesmente pega o valor da linha de cima da coluna que você quer. Por exemplo, se eu fizer lag(conta_carro), eu vou saber qual o valor da coluna conta_carro da linha anterior a que estou verificando. No caso apresentado nesse post, precisamos de uma função que faça o contrário da lag, ao invés de retornar o valor da linha anterior, deve retornar o valor da linha seguinte. Você verá que não existe uma função pronta para esse caso, mas o script é bem simples e se encontra na Parte 5 do código abaixo.

Veja o exemplo completo que você pode simular e acompanhar o passo a passo explicado acima:
**** Parte 1: Cria uma base de clientes ****;
data base_clientes;
    input nome $ carro $ DtCompra mmddyy8.;
    cards;
    Andre Onix 02/05/15
    Andre Palio 12/10/13
    Andre Uno 01/05/14
    Paulo Idea 10/06/15
    Jose Vectra 01/04/16
    Jose Eco 12/05/16 28
    Maria Corsa 10/25/14
    Maria Celta 02/01/16
    Renata Onix 02/09/12
    Renata Palio 06/05/11
    Renata Fit 02/11/16
    Renata Civic 05/22/14
    Michael Fit 07/13/15
    Bianca Clio 09/05/15
    Thais March 08/05/16
    Renan Palio 11/05/13
    Renan Gol 11/05/14
    ;
run;

**** Parte 2: Trata a variavel data ****;
data base_clientes_v2;
    set base_clientes;
    format DtCompra date9.;
run;

**** Parte 3: Ordena pelo nome do cliente e data da compra do veiculo ****;
proc sort data= base_clientes_v2; by nome DtCompra; run;

**** Parte 4: Cria um contador do numero de carros = conta qtas vezes o nome aparece****;
data base_clientes_v3;
    set base_clientes_v2;
    by nome;
    primeiro = first.nome;
    ultimo = last.nome;
    if primeiro = 1 then
    conta_carro = 1;
    else conta_carro+1;
run;

**** Parte 5: Cria uma coluna com o valor da linha seguinte da coluna conta_carro ****;
data base_clientes_v4;
    recno=_n_+1;
    set base_clientes_v3 end=last;
    if not last
    then set base_clientes_v3 (keep=conta_carro rename=(conta_carro=next_conta_carro)) point=recno;
    else call missing(next_conta_carro);
run;

**** Parte 6: Mantem apenas quem tem conta_carro = 1 e que a proxima linha eh 1 tb ****;
data clientes_com_um_carro;
    set base_clientes_v4;
    if conta_carro = 1 and next_conta_carro = 1;
run;

Abbreviation Macro no SAS – Atalho de Códigos

Uma ferramenta bacana do SAS é o Abbreviation Macro, que serve para você salvar trechos de códigos que você utiliza constantemente. Isso economiza um bom tempo. Um exemplo clássico é para fazer os joins dos proc sql e os merge do data step, que todo mundo utiliza e às vezes dá aquele branco, ou aquela preguiça. Com o Abbreviation Macro você pode salvar um exemplo desses códigos e utilizar. É bem simples de utilizar:

1 – Vá em Program e selecione Add Abbreviation Macro:

2 – Digite um nome para o trecho que você quer chamar. No meu exemplo, é um código que eu utilizo para compactar bases no SAS e que eu nomeei COMPACTAR:

Pronto, vá no seu código, escreva COMPACTAR e veja a mágica acontecer (seu código vai aparecer lá!). Fácil assim.

O código de compactar está disponível em: Compactar e Descompactar Bases no SAS

Média Móvel: Explicação, Comando SAS e Função LAG

A maioria das pessoas conhece e utiliza a média no dia a dia. O que alguns não conhecem é a média móvel. O que seria isso?

A média móvel nada mais é do que a média de um determinado número de observações recentes. Por exemplo, suponha que você seja dono de uma oficina e venda peças para automóveis. Suas vendas trimestrais estão representadas pela tabela abaixo:

Você é cauteloso com o seu orçamento, e, para decidir quanto gastar no ano seguinte, você quer verificar a tendência das vendas. Uma alternativa é utilizar a média móvel trimestral, que seria nada mais do que a média dos últimos três meses. Ou seja, você irá sempre pegar a média dos últimos três meses. Isso é útil para verificar se está havendo uma tendência de crescimento ou uma reversão, pois você captura movimentos recentes de vendas:

Simples, não?

Bônus – Média Móvel no SAS:

Para calcular a média móvel no SAS você precisará de algo que identifique os meses anteriores ao que você está analisando, isso pode ser obtido com a função lag().

Vamos supor que a tabela do exemplo acima foi criada no SAS com o nome BASE_VENDAS, contendo as variáveis: Ano e Vendas. Ao utilizar LAG(vendas), obteremos a variável vendas com uma defasagem. Ao utilizar LAG2(vendas), obteremos a variável vendas com duas defasagens:

data Variaveis_Defasadas;
    set Base_Vendas;
    Vendas_M1 = lag(vendas);
    Vendas_M2 = lag2(vendas);
run;

Esse é o resultado:


Agora ficou fácil descobrir como chegar a média móvel, certo?

data Media_Movel;
    set Variaveis_Defasadas;
    Media_3M = SUM(Vendas,Vendas_M1,Vendas_M2)/3;
    DROP Vendas_M1 Vendas_M2;
run;

Simples não?

Apenas para sanar quaisquer dúvidas:

SUM = Soma as variáveis, utilizando a vírgula para separá-las.

DROP = Exclui da tabela as variáveis (as colunas) que você não precisa mais.