SAS
Índice
- LIBNAME
- Aritmética
- Data Step
- Data e Posições
- Consulta de Passagem
- MACRO
- Paralelismo
- 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 ;