SAS

Índice

  1. LIBNAME
  2. Aritmética
  3. Data Step
  4. Data e Posições
  5. Consulta de Passagem
  6. MACRO
  7. Paralelismo
  8. Outros

LIBNAME

1A Criando LIBNAMES

 1
 2/* Com authdomain */
 3LIBNAME DADOS DB2 DATABASE=bancodedados SCHEMA=schema AUTHDOMAIN=usuario;
 4
 5/* Com usuário e senha */
 6LIBNAME PG postgres SERVER='192.168.0.1' DATABASE='DATABASE' PORT='5432' USER='postgres' PASS='SENHA' schema='SCHEMA';
 7
 8/* Para uma pasta */
 9LIBNAME DADOS '/CAMINHO/PARA/PASTA';
10
11/* Para várias pastas com uma mesma LIBNAME */
12LIBNAME DADOS ('/CAMINHO/PARA/PASTA1', '/CAMINHO/PARA/PASTA2');
13
14/* Limpar todas as LIBNAMEs */
15LIBNAME _ALL_ CLEAR;

2 Aritmética

2A Data step

 1data _null_;
 2	ano = year(today());
 3	anomes = (ano * 100) + month(today());
 4	call symputx("anomes", anomes);
 5run;
 6
 7/* O valor de anomes pode ser acessado no código como uma macro. */
 8data dados_saida_&anomes;
 9	set dados_entrada;
10run;

3 Data Step

SINTAXE

1DATA New-Dataset-Name (OPTIONS);
2    SET Existing-Dataset-Name (OPTIONS);
3    .
4    .
5    .
6RUN;

Criando novas colunas bmi e height2. Excluindo as colunas height e weight na base de saída.

1DATA sample_new_vars (DROP = height weight);
2    SET sample;
3    bmi = (weight / (height*height) ) * 703;
4    height2 = height * 0.0254;
5RUN;

Filtrando as colunas da base de entrada. Mantendo as colunas ids e colunas apenas com caracteres. No segundo caso apenas as colunas com valores numéricos.

1DATA sample_stringonly;
2   SET sample(KEEP=ids _CHAR_);
3RUN;
4
5DATA sample_numericonly;
6   SET sample(KEEP=ids _NUMERIC_);
7RUN;

Renomeando as colunas.

1 RENAME = (oldvariable1=newvariable1 oldvariable2=newvariable2 ...)
1DATA sample2 (RENAME=(Gender=Sex DOB=Date_of_Birth));
2    SET sample;
3RUN;

Usando switch/select

 1data Heart / view=Heart;
 2	set sashelp.heart;
 3	select (Smoking_Status);
 4	   when ('Non-smoker')        Smoking_Cat=1;
 5	   when ('Light (1-5)')       Smoking_Cat=2;
 6	   when ('Moderate (6-15)')   Smoking_Cat=3;
 7	   when ('Heavy (16-25)')     Smoking_Cat=4;
 8	   when ('Very Heavy (> 25)') Smoking_Cat=5;
 9	   otherwise                  Smoking_Cat=.;
10	end;
11run;

4 Datas e Posições

4a Buscar mês e ano atual com macro

1%LET ANO = %sysfunc(year("&sysdate"d));
2%LET MES = %sysfunc(month("&sysdate"d));

4b Criando ANOMES - aritmética

1%LET MES_INI    = 1;
2%LET MES_FIM    = %sysfunc(month("&sysdate"d));
3%LET MES        = %sysfunc(month("&sysdate"d));
4%LET ANOMES_INI = %eval(100*&ANO + &MES_INI);
5%LET ANOMES     = %eval(100*&ANO + &MES_FIM);

Convertendo yyyymmdd de caractere para data !revisar

1data want_where_num;
2  set have_with_num_date;
3  date_new = input(put(date,8.), yymmdd8.);
4  format date_new weekdate9. ;
5run;

Formata datas do SAS para DB2

1call symputx('mesano0',cat("'",put(intnx('month',intnx('year',today(),-0),-1),ddmmyyp10.),"'"));

Criando datetime

 1PROC SQL;
 2	CREATE TABLE BIC2_COUNT AS
 3	SELECT 
 4		MEMNAME
 5		,NOBS
 6		,dhms('23nov21'd, 23, 6, 11) format datetime20.  as posicao
 7	from dictionary.tables
 8    where 
 9		libname = "LIBNAME" AND 
10		MEMNAME = "MEMNAME"
11;QUIT;

Salvando dados de uma tabela em variáveis:

1proc sql;
2	select posicao, mes, ano
3	into :posicao , :mes , :ano
4	from datas;
5quit;

Consulta de passagem (pass-through)

Consulta de passagem com authdomain

 1proc sql;
 2	connect to db2 (DATABASE=DB01 AUTHDOMAIN=USUARIO);
 3	create table dados as 
 4	select * from connection to db2 (
 5		SELECT 
 6		*
 7		FROM schema.tabela 
 8		WHERE data_ref = current_date;
 9	) a;
10	disconnect from db2;
11quit;

Consulta de passagem com usuário e senha

1proc sql;
2	connect to postgres (server='192.168.0.1' port=5432 user=usuario password=senha db=banco);
3	create table dados as 
4	select * from connection to postgres (
5		select * from schema.tabela;
6	) a;
7	disconnect from postgres;
8quit;

Executar SQL num banco de dados através do SAS.

1PROC SQL;
2	connect to db2 (authdomain=meuusuario database=meubancodedados);
3	execute by db2 (delete from meuschema.minhatabela where coluna = 1338);
4	disconnect from db2;
5QUIT;

MACRO

Sintaxe

 1%MACRO <macro name>(Param1, Param2,….Paramn);
 2
 3Macro Statements;
 4
 5%MEND;
 6
 7/* Calling a Macro program */
 8%MacroName (Value1, Value2,…..Valuen);
 9
10
11
12/* OUTRO EXEMPLO */
13%MACRO show_result(make_ , type_);
14	proc print data = sashelp.cars;
15	where make = "&make_" and type = "&type_" ;
16	   TITLE "Sales as of &SYSDAY &SYSDATE";
17	run;
18%MEND;
19
20%show_result(BMW,SUV);

Macro sintaxe IF ELSE

1%IF condition %THEN action;  
2	%ELSE %IF condition %THEN action;  
3%ELSE action;  
4
5%IF condition %THEN %DO;  
6	action;  
7%END

Paralelismo

Executando duas consultas em paralelo

 1options autosignon sascmd = "!sascmd";  
 2
 3SIGNON TASK1;
 4rsubmit TASK1 wait=no;
 5	/* BUSCANDO OS DADOS 1 */
 6	data _null_;
 7		mes = month(today());
 8		put mes;
 9	run;
10endrsubmit;
11
12signon task2;
13rsubmit task2 wait=no;
14	/* BUSCANDO OS DADOS 2*/
15	data _null_;
16		mes = year(today());
17		put mes;
18	run;
19endrsubmit; 
20
21waitfor _all_;
22signoff _all_;

Fonte: https://www.lexjansen.com/sesug/2016/PA-265_Final_PDF.pdf https://www.lexjansen.com/nesug/nesug05/io/io2.pdf https://stackoverflow.com/questions/36284342/sas-program-with-local-library-in-set-statement

Salvando os dados em paralelo numa LIBNAME.

 1options autosignon sascmd = "!sascmd"; 
 2
 3SIGNON TASK1 SIGNONWAIT=NO;
 4rsubmit TASK1 wait=no;
 5
 6%PUT NOTE-: iniciando_1;
 7 
 8libname mylib 'caminho';
 9
10proc sql;
11	CONNECT TO db2 (DATABASE=bancodedados AUTHDOMAIN=usuario);
12	create table mylib.tabela_1 as 
13	select * from connection to db2 (
14		SELECT * from schema.tabela ;
15	) a ;
16quit;
17 
18%PUT NOTE-: finalizando_1;
19endrsubmit;
20 
21
22signon task2 SIGNONWAIT=NO;
23rsubmit task2 wait=no;
24
25%PUT NOTE-: iniciando_2;
26
27/* mesmo caminho da lib anterior, muda apenas o nome */
28libname mylib2 'caminho';
29
30PROC SQL;
31CONNECT TO db2 (DATABASE=bancodedados AUTHDOMAIN=usuario);
32    CREATE TABLE mylib2.tabela_2 AS
33    SELECT * FROM CONNECTION TO DB2
34    (
35        SELECT * from schema.outra_tabela
36     ) a;
37	DISCONNECT FROM DB2;
38QUIT;
39 
40%PUT NOTE-: finalizando_2;
41endrsubmit; 
42
43*waitfor _all_;
44signoff _all_;

Substituir tabela caso não dê erro.

 1
 2%macro tratamentoDeErros2;
 3
 4	%if &sysErr < 6 %then %do;
 5		data interno.tabela_1;
 6			set tabela_1;
 7		run;
 8	%end;
 9
10%mend;
11
12
13%tratamentoDeErros2;

Outros

Buscar nome da tabela mais recente por sufixo ANOMES.

 1proc sql noprint;
 2    select max(memname) as membername
 3    into :inadAtual separated by '","'
 4    from sashelp.vmember
 5    where libname = "DADOS"
 6      AND memname like "TABELA_2022%"
 7;
 8QUIT;
 9
10
11
12
13/* outra versao. precisa ser atualizada */
14proc sql noprint;
15	select 
16		input(
17			substr(
18				max( scan(memname,5,'_') )
19			,5,2)
20		, 6.)
21		,max( scan(memname,5,'_') )
22	into :mes_max, :anomes_max
23	from dictionary.tables
24	where 
25		libname = upcase("rlzmci")
26		and memname like 'IND_000000977_RLZ_ANL_%';
27quit;
28
29%put &mes_max;

Criando um array separado por vírgula

Pode ser usado para quando quer se encarteirar MCIs por vários meses diferentes.

 1DATA AUXILIAR;
 2    DO I=&MES_INI. TO &MES_FIM.;
 3        OUTPUT;
 4    END;
 5RUN;
 6
 7PROC SQL NOPRINT;
 8    SELECT I INTO :meses_str Separated By ' '
 9        FROM AUXILIAR;
10    DROP TABLE AUXILIAR;
11RUN;
12
13%PUT &meses_str;

Selecionar linhas de forma aleatória numa tabela.

1PROC SURVEYSELECT 
2	DATA=TABELA_ENTRADA
3	OUT=TABELA_SAIDA
4	METHOD=SRS
5	SAMPSIZE=100000 SEED=1234567;
6RUN;

Juntar várias tabelas com mesmo radical e adicionar a tabela de origem.

 1PROC SQL NOPRINT;
 2	SELECT 'DADOS.'||TRIM(MEMNAME) AS MEMNAME
 3	INTO :TABELAS SEPARATED BY ' '
 4	FROM SASHELP.VMEMBER
 5	WHERE LIBNAME = "DADOS"
 6	AND MEMNAME LIKE "TABELA_2023%"
 7;QUIT;
 8
 9DATA TODAS_TABELAS;
10	SET &TABELAS INDSNAME=DSNAME;
11
12	/* NESSE CASO PEGO APENAS PARTE DO NOME DA TABELA DE ENTRADA */
13	ANOMES_ARQ = INPUT(SCAN(DSNAME, -1, '_'), 6.);
14RUN;

Limpar acentos - preciso ajustar. adiciona underscore.

 1%MACRO LIMPAR_ACENTO(STRING);
 2
 3	&STRING = UPCASE(&STRING);
 4	&STRING = TRANWRD(&STRING, 'Á', 'A');
 5	&STRING = TRANWRD(&STRING, 'É', 'E');
 6	&STRING = TRANWRD(&STRING, 'Í', 'I');
 7	&STRING = TRANWRD(&STRING, 'Ó', 'O');
 8	&STRING = TRANWRD(&STRING, 'Ú', 'U');
 9
10	&STRING = TRANWRD(&STRING, 'Ã', 'A');
11	&STRING = TRANWRD(&STRING, 'Ê', 'E');
12	&STRING = TRANWRD(&STRING, 'Ô', 'O');
13	&STRING = TRANWRD(&STRING, 'Ç', 'C');
14	&STRING = TRIM(&STRING);
15	
16
17%MEND LIMPAR_ACENTO;

Concatenar agregar array aggregate Juntar valores de linhas por coluna numa linha.

cod1 cod2
A 1
A 2
A 3
B 5
B 6

Após rodar ficará assim

cod1 cod2s
A 1,2,3
B 5,6
 1data TEST3(DROP=CD_MDLD RENAME=CAT=MODALIDADES) ;
 2
 3    length cat $1000;
 4
 5    retain cat ;
 6
 7set PRDS ;
 8
 9    by CD_PRD notsorted ;
10
11        if first.CD_PRD then cat = cats(CD_MDLD) ;
12
13            else cat = catx(' , ',cat,CD_MDLD) ;
14
15        if last.CD_PRD then output ;
16
17run ;