Vous êtes sur la page 1sur 393

Il SISTEMA SAS

Un potente strumento software di uso generale

Rolando Bianchi Bandinelli Edoardo Bracci Domenico Laforenza


1

Autori
Rolando Bianchi Bandinelli (Siena, 1946) ricercatore presso l'Istituto CNUCE del Consiglio Nazionale delle Ricerche. Si laureato in Scienze dell'Informazione presso il Dipartimento di Informatica dell'Universit di Pisa. Dal 1970 si occupato di Performance Evaluation e Capacity Management di grandi installazioni scientifiche E.D.P.. Dal 1982 al 1987 stato responsabile della Servizio Organizzazione e Valutazione del CNUCE. Ha svolto una intensa attivit di consulenza e formazione nell'ambito dei linguaggi della IV generazione, in particolare del sistema SAS, presso numerosi enti pubblici e privati. Attualmente divide la sua attivit tra il coordinamento del Progetto internazionale ASTRA e la conduzione del Reparto di Ricerca Dimensionamento e Valutazione di Sistemi Informatici del CNUCE. Edoardo Bracci (Bergamo, 1947) ricercatore presso l'Istituto CNUCE del Consiglio Nazionale delle Ricerche. Si laureato in Fisica all'Universit di Pisa. Dopo aver usufruito di uno stage presso i laboratori CERN di Ginevra, dal 1973 ha svolto ininterrottamente l'attivit di ricerca presso il CNUCE, soprattutto nel settore della valutazione delle prestazioni di sistemi informatici, partecipando a progetti di ricerca in collaborazione con industrie ed enti pubblici. Fa parte di commissioni e gruppi di studio istituiti dal CNR su scala nazionale, finalizzati a promuovere lo sviluppo delle tecnologie informatiche, in particolare delle reti, all'interno dell'Ente. Ha svolto in questi ultimi anni una intensa attivit di consulenza e formazione nell'ambito dei linguaggi della IV generazione, in particolare del sistema SAS, presso numerosi enti pubblici e privati. Domenico Laforenza (Acquaviva delle Fonti, 1952) ricercatore presso l'Istituto CNUCE del Consiglio Nazionale delle Ricerche. Si laureato in Scienze dell'Informazione presso il Dipartimento di Informatica dell'Universit di Pisa nel 1977, ove stato assistente al corso di Sistemi per l'elaborazione dell'Informazione II, negli anni accademici 1977/78 e 1978/79. Nell'ambito del CNUCE, sino al 1981 si interessato di pianificazione ed evoluzione del Centro di Elaborazione Dati; dal 1981 si occupa di supercalcolatori in qualit di responsabile del Reparto di ricerca "Calcolo Vettoriale e Parallelo". Negli anni 1985 e 1986 ha contribuito a coordinare le attivit del Progetto Strategico Calcolo Parallelo del CNR. Dall'ottobre 1986 professore a contratto al corso di Metodologia e tecnica del calcolatore applicata al Servizio Sociale, presso la Scuola Superiore di Servizio Sociale dell'Universit di Pisa. E' stato docente e consulente di aziende ed enti pubblici e privati per quanto concerne la formazione nell'area dei linguaggi di IV generazione, con particolare riguardo al sistema SAS.

Indice

Prefazione..................................................................................................................... 7 Introduzione.................................................................................................................. 9 1. Il sistema SAS..................................................................................................... 12 1.1. Storia del prodotto .................................................................... 12 1.2. Ambienti operativi .................................................................... 13 1.3. Schema generale e potenzialit.................................................. 13 1.4. Alcuni termini di uso frequente ................................................. 15 1.5. Come si presentano i problemi al Sistema SAS ......................... 17 1.5.1. Come si scrivono i passi SAS.................................................... 18 1.5.2. Come si sottomettono i passi al sistema SAS............................. 23 1.5.2.1. Modo interattivo ....................................................................... 24 1.5.2.2. Modo Batch .............................................................................. 25 1.5.2.3. Modo semi-interattivo............................................................... 26 2. Il passo di DATA ................................................................................................ 29 2.1. Struttura degli archivi SAS ....................................................... 29 2.2. Creazione di un archivio SAS ................................................... 33 2.3. La compilazione del passo di DATA......................................... 37 2.4. Lesecuzione del passo di DATA .............................................. 41 2.5. La dichiarazione DATA............................................................ 42 2.6. La dichiarazione CARDS.......................................................... 43 2.7. La dichiarazione INPUT ........................................................... 44 2.7.1. INPUT a colonne ...................................................................... 45 2.7.2. INPUT a lista............................................................................ 46 2.7.3. INPUT a formati....................................................................... 48 2.7.4. Puntatori di colonna e di riga .................................................... 50 2.8. La dichiarazione di assegnazione .............................................. 54 2.9. La dichiarazione IF-THEN-ELSE ............................................. 57 2.10. La dichiarazione DO-END........................................................ 62 2.11. La dichiarazione RETAIN e la totalizzazione............................ 64 2.12. La dichiarazione SUM .............................................................. 67 2.13. La dichiarazione SET................................................................ 68 2.14. Le dichiarazioni DROP e KEEP................................................ 71 2.15. La dichiarazione RENAME ...................................................... 72 2.16. DROP, KEEP e RENAME date come opzioni .......................... 75 2.17. Le dichiarazioni IF Subsetting e DELETE ................................ 77 2.18. La dichiarazione OUTPUT ....................................................... 80 2.19. La dichiarazione LENGTH ....................................................... 81 2.20. Qualche regola per una buona scrittura dei programmi .......... 84 3. Il passo di PROC................................................................................................. 87 3.1. Generalit ................................................................................. 87 3.2. Classificazione delle procedure................................................. 90 3.2.2. Le procedure per la produzione dei report ................................. 91 3

3.2.3. Le procedure di utilit ............................................................... 92 3.3. Elementi costituenti un passo di PROC ..................................... 94 3.3.1. La dichiarazione PROC ............................................................ 94 3.3.2. Le dichiarazioni VARIABLES e BY......................................... 96 3.3.3. Altre dichiarazioni di uso generale ............................................ 98 3.4. Visualizzazione delle opzioni correnti: PROC OPTIONS........ 106 3.5. Ordinamento di un archivio: PROC SORT.............................. 107 3.6. Visualizzazione di un archivio ................................................ 109 3.6.1. PROC CONTENTS ................................................................ 109 3.6.2. PROC PRINT ......................................................................... 111 3.6.3. Cenno alla PROC QPRINT..................................................... 119 4. Ulteriori elementi del passo di DATA ............................................................... 121 4.1. La gestione delle date e dei tempi............................................ 121 4.2. Le funzioni per la manipolazione di stringhe di caratteri ......... 128 4.2.1. Le funzioni INDEX e SUBSTR .............................................. 130 4.2.2. La funzione LENGTH ............................................................ 132 4.2.3. Loperatore di concatenazione e la funzione TRIM ................. 133 4.2.4. La funzione SCAN.................................................................. 134 4.3. La gestione dei valori mancanti............................................... 136 4.4. Altre dichiarazioni del passo di DATA.................................... 140 4.4.1. Le variabili automatiche _N_ ed _ERROR_............................ 141 4.4.2. La dichiarazione RETURN ..................................................... 142 4.4.3. Etichette e dichiarazione GO TO............................................. 144 4.4.4. La dichiarazione LINK ........................................................... 145 4.4.5. La dichiarazione DO ............................................................... 146 4.4.6. La dichiarazione ARRAY ....................................................... 150 4.5. Le conversioni fra dati numerici e dati non numerici............... 154 4.5.1. Conversioni da variabili non numeriche a variabili numeriche. 156 4.5.2. Conversioni da variabili numeriche a variabili non numeriche. 158 5. Gestione degli archivi........................................................................................ 163 5.1. La lettura e scrittura degli archivi in SAS ................................ 163 5.2. La lettura degli archivi non SAS ............................................. 165 5.3. La dichiarazione INFILE ........................................................ 167 5.3.1. Lettura da archivi non SAS con un diverso numero di record.. 171 5.4. Complementi della dichiarazione INPUT a lista...................... 173 5.5. Lettura di archivi gerarchici .................................................... 176 5.6. Uso del doppio @@................................................................ 179 5.7. Lettura di archivi SAS con la dichiarazione SET..................... 180 5.8. Lettura di archivi SAS con la dichiarazione MERGE .............. 183 5.9. I parametri END, FIRST., LAST. E IN ................................... 189 5.10. La dichiarazione UPDATE ..................................................... 192 5.11. Esempi di utilizzo delle dichiarazioni MERGE ed UPDATE... 193 6. Produzione di rapporti....................................................................................... 199 6.1. Cosa sintende per rapporto..................................................... 199 6.2. La procedura PRINT............................................................... 200 6.3. I formati di uscita.................................................................... 201 6.4. La procedura FORMAT .......................................................... 203 4

6.5. La procedura FORMS............................................................. 206 6.6. La procedura CHART............................................................. 210 6.7. La procedura CALENDAR ..................................................... 219 6.8. La procedura TABULATE...................................................... 228 6.9. La procedura PLOT ................................................................ 255 6.10. Introduzione alla produzione di rapporti personalizzati ........... 263 6.10.1. La dichiarazione PUT e FILE.................................................. 263 6.10.2. Alcuni esempi......................................................................... 267 7. Analisi dei dati cenni di procedure statistiche .................................................... 272 7.1. Considerazioni generali........................................................... 272 7.2. Uso della procedura MEANS.................................................. 273 7.3. Uso della procedura FREQ ..................................................... 278 7.4. Uso della procedura CORR..................................................... 286 8. Il linguaggio SAS-macro ................................................................................... 291 8.1. Introduzione al linguaggio macro............................................ 291 8.2. Concetti generali..................................................................... 292 8.3. Il linguaggio SAS-macro e le macro-varabili........................... 293 8.4. Macro-istruzione %LET e macro-funzioni %STR e %NRSTR 296 8.5. Macro-istruzione %PUT ......................................................... 300 8.6. Le macro................................................................................. 301 8.7. Macro-variabili locali e globali ............................................... 305 8.8. Descrizione delle principali macro-istruzioni .......................... 309 8.9. Richiamo di macro stile istruzione ...................................... 310 8.10. Macro richiamabili come comandi .......................................... 313 8.11. Definizione automatica delle macro al momento del richiamo. 316 9. Cenni di SAS/FSP ............................................................................................. 319 9.1. Generalit del SAS/FSP .......................................................... 319 9.2. Cataloghi SAS ........................................................................ 321 9.3. La procedura FSEDIT............................................................. 324 9.3.1. Creazione di un archivio SAS ................................................. 324 9.3.2. Aggiornamento di un archivio SAS......................................... 326 9.3.3. Definizione e modifica di maschere-video............................... 327 9.4. La procedura FSBROWSE...................................................... 328 9.5. La procedura FSLETTER ....................................................... 331 9.5.1. Personalizzazione ed invio delle lettere con la PROC FSEDIT 333 9.6. La procedura FSCALC ........................................................... 335 10. Cenni di SAS/GRAPH .................................................................................... 342 10.1. Generalit del SAS/GRAPH ................................................... 342 10.2. Panoramica delle principali procedure..................................... 343 10.3. Panoramica delle principali dichiarazioni................................ 346 10.4. Esempi di alcune PROC.......................................................... 347 Appendice A: Il SAS Display Manager System (DMS)............................................. 366 A.1 I comandi di linea (line commands) ................................................................ 367 A.2 I comandi della linea COMMAND ................................................................. 372 A.3 I comandi della linea COMMAND ed i tasti funzionali .................................. 381 Appendice B: I comandi di sistema ........................................................................... 383 B.1 Ambiente OS/MVS........................................................................................ 384 5

B.2 Ambiente TSO............................................................................................... 385 B.3 Ambiente VM/CMS....................................................................................... 386 B.4 Ambiente DOS/VSE...................................................................................... 387 B.5 Ambiente VMS.............................................................................................. 388 B.6 Ambiente PC ................................................................................................. 389 Appendice C: Bibliografia......................................................................................... 390 Appendice D: Elenco marchi registrati e convenzioni................................................ 392

Prefazione

L'idea di scrivere un libro avente per oggetto il sistema SAS (Statistical Analysis System) nasce dalla nostra esperienza di docenti a corsi sull'argomento durante i quali, sempre pi spesso, i partecipanti (personale di enti pubblici e privati, di centri di ricerca, di universit, ecc.) manifestavano delusione nell'apprendere la mancata esistenza di un testo introduttivo sull'argomento scritto in lingua italiana. Questa mancanza, in molti casi, generava un senso di rigetto verso il sistema SAS divenendo, per alcuni, un deterrente per il buon esito del corso. Inoltre, la documentazione relativa al prodotto del SAS Institute Inc., oggettivamente troppo vasta, dovendo necessariamente coprire un ampio spettro di applicazioni del sistema SAS. In aggiunta, l'insieme dei manuali a disposizione comprende anche la documentazione relativa alle specifiche di interazione tra il sistema SAS e i tanti sistemi operativi che lo "ospitano" (VM/CMS, MVS/TSO, VMS, PRIMOS, MS/DOS, UNIX, ecc.) Occorreva quindi un testo che raccogliesse, in maniera ragionata, vari argomenti di interesse "non sporadico" sparsi su pi volumi della nutrita documentazione tecnica esistente. Il libro si rivolge principalmente a tutti coloro che hanno la necessit di avere a disposizione uno strumento software facile da usare, dotato di un linguaggio di programmazione ad alto livello e di un notevole insieme di procedure "preconfezionate" di pronto uso. Non esistendo limiti particolari all'utilizzo di un tale strumento, esso adatto per elaborare dati provenienti da esperimenti effettuati nelle pi disparate aree come, ad esempio: le scienze sociali e fisiche, l'analisi finanziaria, il marketing, la medicina, la farmacologia, ecc. ecc.. Nel definire i criteri di base per realizzare questo libro, ci siamo posti la domanda se dare al testo una connotazione tecnico-applicativa specifica, legandolo ad una applicazione particolare, oppure se considerarlo un primo testo introduttivo di uso generale scegliendo esempi tra i pi semplici che servissero per come spunto per tanti casi concreti per i quali il sistema SAS rappresenta un utile strumento di elaborazione ed analisi dei dati. Dopo una attenta analisi del mercato a cui il libro principalmente si rivolge, abbiamo scelto la seconda ipotesi, demandando gli approfondimenti di argomenti di particolare interesse (es.: le nuove funzioni del prodotto introdotte negli ambienti MS-DOS ed UNIX) a testi successivi, da intendersi come la naturale evoluzione del presente volume. 7

In conclusione desideriamo ringraziare i nostri colleghi del CNUCEIstituto del Consiglio Nazionale delle Ricerche di Pisa che, con consigli ed osservazioni hanno permesso la buona riuscita dell'opera. Particolare ringraziamento va anche al SAS Institute Italia per la documentazione ed il competente supporto tecnico fornitoci prima e durante le fasi di scrittura del libro.

Rolando Bianchi Bandinelli Edoardo Bracci Domenico Laforenza

Introduzione

Molti (che da ora in avanti indicheremo con il termine "utenti finali") hanno in qualche occasione udito che il computer potrebbe aiutarli nel loro lavoro e, mossi da necessit immediate, si attendono da esso soluzioni pronte con sforzi minimi se non, addirittura, nulli. Purtroppo questo non ancora del tutto vero ed i desiderata dell'utente finale, derivanti dalla giusta motivazione che il suo interesse risiede principalmente nell'analisi dei risultati prodotti dall'elaboratore e non nelle azioni intese a far s che il computer elabori i dati ad esso forniti in ingresso (la programmazione), molto spesso si scontrano con l'attuale stato dell'arte dei sistemi informatici. Infatti, nonostante il rapido evolvere dell'informatica, non ci sentiamo di poter affermare che l'utente finale possa utilizzare i computer senza aver prima subito una "iniziazione" che, spesso, rappresenta un vero e proprio trauma perch egli costretto ad apprendere delle informazioni di base delle quali, a suo avviso, farebbe volentieri a meno. Inoltre, acquisire competenze su un nuovo argomento, apparentemente del tutto scorrelato rispetto al proprio campo di attivit, pu risultare difficoltoso e frustrante, e questa considerazione si applica, ovviamente, anche all'apprendimento del sistema SAS. Per evitare, per quanto possibile, questa situazione, abbiamo cercato di introdurre i concetti di base del sistema SAS usando un linguaggio semplice, includendo le definizioni dei termini tecnici incontrati, in maniera da diluire nel tempo la complessit degli argomenti trattati, dando cos al lettore in prima istanza solo quelle informazioni di "stretta necessit" per un uso immediato del sistema SAS, demandando eventuali approfondimenti alla lettura dei capitoli via via pi avanti.

Strumenti software per l'utente finale


In quasi tutti gli ambienti, la domanda di servizi di informatica (in particolare di applicazioni software) in rapida e continua crescita e, nel contempo, il costo dello hardware in continua diminuzione; questi due fattori fanno s che le organizzazioni tendano a dotarsi di elaboratori sempre pi potenti e ricchi di risorse. Ma, le aumentate capacit dei sistemi, inducono una pi massiccia richiesta di realizzazione di nuove e pi complicate 9

applicazioni da parte dell'utente finale. Purtroppo, la domanda di nuove applicazioni operata dagli utenti ai rispettivi centri di elaborazione dati cresce pi velocemente rispetto all'offerta che questi ultimi sono in grado di erogare; in particolare rimane insufficiente il numero di programmatori da destinare allo sviluppo del software applicativo richiesto. Nasce quindi la necessit di scegliere degli strumenti capaci di mettere l'utente finale in grado di svilupparsi da solo le proprie applicazioni. Esistono oggi sul mercato moltissimi sistemi software (chiamati anche pacchetti o package) che sulla carta si definiscono strumenti per l'utente finale, ma in alcuni casi questa definizione, largamente utilizzata in sede di vendita, risulta all'atto pratico, poco consona con quelle potenzialit che normalmente un utente si attenderebbe dal prodotto. Come decidere quindi se un sistema possiede le caratteristiche di essere realmente uno strumento per l'utente finale? A questo proposito, esiste una regola empirica, formulata da un noto esperto d'informatica di fama mondiale, che recita cos: Noi possiamo classificare un sistema software come usabile direttamente dall'utente finale quando egli in grado di apprenderne le modalit d'uso dopo un breve corso, e non le dimentica anche se non lo usa per qualche settimana. Detta regola enfatizza primariamente la versatilit di un sistema software, cio la sua caratteristica di risultare di pronto e facile utilizzo. Nell'ambiente dell'informatica esiste un assioma secondo il quale "tante meno cose un sistema in grado di fare, tanto meno esso complicato da usare". Seguendo alla lettera questo assioma, potremmo trovarci nella situazione di dover scegliere tra tantissimi pacchetti presenti sul mercato in quel momento, ciascuno dei quali: fa poche cose ma specializzate; gestisce i dati in maniera diversa dagli altri; utilizza un linguaggio simile a quello adottato dagli altri, ma comunque differente. Ovviamente, necessitando di un cospicuo numero di funzioni offerte dai singoli pacchetti, saremo costretti ad acquisirne diversi, andando incontro probabilmente ai seguenti problemi: necessit di trattare con pi fornitori, con la conseguenza di dover gestire diversi contratti software; costo derivante da acquisizioni multiple generalmente 10

pi elevato di quello di una singola acquisizione, anche in considerazione che, molto spesso, software diversi richiedono hardware diversi; complicazione nella gestione derivante dal fatto che, generalmente, la manutenzione di pi pacchetti risulta pi onerosa di quella di un pacchetto; necessit di imparare pi linguaggi; incompatibilit dei dati tra un pacchetto e l'altro. Come si evince dalla lista di problemi elencati, cos facendo avremmo infranto la regola della facilit d'uso in base alla quale abbiamo cominciato l'indagine. Come risolvere questo annoso problema ? Scegliendo un pacchetto integrato di uso generale, disponibile in versioni adattate per la maggior parte degli elaboratori oggi presenti sul mercato. Il sistema SAS rappresenta un buon esempio di acquisizione ragionata che soddisfa la quasi totalit dei requisiti visti in precedenza.

11

1. Il sistema SAS

1.1.

Storia del prodotto

Il sistema SAS un prodotto software costituito da un linguaggio di programmazione e da una famiglia di pacchetti, ciascuno composto da un insieme di programmi pre-confezionati e di pronto uso (procedure), che adottano metodi di elaborazione per la risoluzione di problemi di statistica, econometria, ricerca operativa, grafica, ecc.. Il sistema SAS prodotto da SAS Institute Inc. (Box 8000 Cary, North Carolina 27512-8000), societ che rappresentata nel mondo da consociate e distributori nazionali e che in Italia, dal 1987, presente con una propria filiale a Milano in via S. Martino della Battaglia, 17. Il sistema SAS nasce da una intelligente idea avuta da un gruppo di studenti e docenti dell'Universit americana del North Carolina (in particolare da Jim Goodnight, attuale presidente della societ) che intorno al 1970 pensarono di realizzare un prodotto software composto da una libreria di programmi di natura statistica e di uso comune. Tale strumento si rivolgeva a tutti gli operatori del settore, in modo che questi ultimi potessero direttamente concentrare la loro attenzione sui risultati forniti da detti programmi senza doverli scrivere. In altre parole essi intuirono che, a causa della complessit dei linguaggi di programmazione esistenti allora, generalmente l'utilizzatore desiderava essere svincolato dall'imparare a scrivere i programmi, per non trasformarsi in programmatore, figura professionale senza dubbio interessante, ma spesso fuorviante rispetto alle concrete necessit professionali dell'utente. Con il passare degli anni, mutando lo scenario informatico mondiale e con esso le necessit degli utenti, il sistema SAS andato trasformandosi, da solo potente pacchetto statistico, a strumento per uso generale (general purpose software tool). Inoltre, molte altre procedure tipiche di svariate discipline tecnico-scientifiche, sono andate ad aggiungersi a quelle statisti12

che, tanto che oggi esistono molti prodotti SAS addizionali disponibili per l'utente.

1.2.

Ambienti operativi

La politica seguita inizialmente da SAS Institute Inc. fu quella di realizzare il sistema SAS per quegli elaboratori aventi una maggiore diffusione sul mercato mondiale, dotati di risorse hardware sufficienti a soddisfare le pesanti necessit di un prodotto in fase di continua evoluzione. Per questa ragione le prime implementazioni del prodotto riguardarono il mondo dei grandi elaboratori (mainframe) IBM con particolare riguardo a quelli con sistemi operativi OS, I successi di mercato ottenuti in breve tempo dal prodotto, indussero SAS Institute Inc. ad adattare il prodotto anche per i minicalcolatori (Vax-Digital Equipment, Eclipse-Data General, Prime, ecc.). Con l'avvento del personal computer si schiudeva un enorme mercato per questo prodotto ma, affinch potesse essere predisposto per questi elaboratori di relativamente limitate risorse hardware, occorreva riscriverlo interamente adoperando un linguaggio dotato di elevate capacit di ottimizzazione del codice macchina e tale da essere supportato da un notevole numero di costruttori di microcalcolatori. Per queste ragioni il sistema SAS per personal computer (SAS/PC) stato interamente riscritto in linguaggio C; attualmente sono gi stati trasportati nella versione SAS/PC un buon numero di pacchetti specializzati facenti parte della famiglia SAS. Oggi il sistema SAS disponibile su una estesa gamma di ambienti differenti, dal grande e medio calcolatore al personal computer; infatti SAS Institute Inc. tende a fornire un prodotto avente le medesime potenzialit in tutti gli ambienti elencati (pur con le ovvie limitazioni imposte al prodotto dallo hardware degli elaboratori su cui esso "gira") in modo che l'utente possa disporre di un sistema configurabile dinamicamente a misura delle sue esigenze.

1.3.

Schema generale e potenzialit

Il sistema SAS pu essere schematizzato come un sistema composto da un "pianeta principale" (SAS/Base o parte generale del prodotto) attorno al quale gravitano tanti "satelliti" (pacchetti SAS per usi specifici) come rappresentato nella figura 1.1. L'utente che intenda lavorare con tale strumento dovr imparare quelle regole sintattiche che sono alla base del 13

linguaggio SAS e comincer ad usare quelle procedure che riterr necessarie ai fini delle proprie analisi. Il tempo che egli dedicher all'apprendimento dei concetti basilari del sistema SAS e della sua filosofia di funzionamento, rappresenter un investimento che gli frutter quando egli vorr utilizzare le procedure facenti parte dei pacchetti satellite specializzati; infatti, le regole sintattiche di scrittura per l'uso delle singole componenti sono identiche. Dovranno essere cambiati solo i nomi delle procedure da richiamare e le eventuali specifiche di funzionamento (dette anche: specifiche di personalizzazione) delle stesse, che dipendono dal tipo di elaborazione che l'utente intende fare.
SAS/QC Controllo di qualit SAS/FSP Data Entry SAS/SHARE Gestione archivi

SAS/ETS Econometria

SAS/OR

SAS/BASE
Linguaggio e procedure di uso generale

Ricerca Operativa

SAS/STAT Statistica

SAS/AF Gestione menu SAS IMS-DL/1 Banche Dati

SAS/GRAPH Grafica

SAS/IML Gestione matrici

Figura 1.1: Schema generale del prodotto SAS Il sistema SAS ha un linguaggio di programmazione "ad alto livello" pi semplice e potente di altri, quali Cobol, Fortran, PL/I, ecc., (classificati commercialmente come linguaggi di III Generazione) e viene ormai generalmente collocato dell'area dei sistemi di IV Generazione. La sua sintassi richiama il linguaggio inglese e soprattutto risulta facile da ricordare anche a chi lo usa sporadicamente. La parte base del sistema SAS mette a disposizione dell'utente strumenti software per: 14

memorizzare e ritrovare informazioni; elaborare dati mediante la scrittura di semplici programmi; produrre tabulati standard, utilizzando procedure di pronto uso, o personalizzati mediante potenti dichiarazioni del linguaggio; analizzare dati sottoponendoli ad una nutrita serie di procedure di uso generale; gestire gli archivi (accodare, fondere, aggiornare, ecc.) in maniera semplice ed efficiente. Il sistema SAS in grado di leggere dati presenti su qualsiasi supporto (terminale, schede, dischi, nastri, floppy disk, ecc.) scritti con formati differenti (numerici e non, binari, impaccati (packed), tempi e date, ecc.). Affinch i dati letti possano essere successivamente elaborati dalle procedure SAS necessario che essi siano sistemati sotto forma di archivi SAS. Alle regole da seguire per la creazione di un archivio SAS dedicata parte del capitolo 2.

1.4.

Alcuni termini di uso frequente

Prima di addentrarci nella lettura delle rimanenti parti di questo libro, nell'intento di permettere una pi facile lettura del testo a chi per la prima volta si affacciasse al mondo dell'informatica, opportuno dare alcune definizioni, cio stabilire un glossario di base composto da quei termini che in seguito spesso incontreremo. Cos' un dato Per dato si intende un valore numerico o non numerico che sar oggetto di elaborazione. Esempi di dati tipicamente numerici sono: altezza di un individuo; stipendio di un dipendente; pressione sanguigna di un paziente; rapporto di cambio di una moneta; ecc.. Esempi di dati non numerici (o alfanumerici) sono: nome e cognome di un soggetto; indirizzo di un abbonato; 15

classificazione in base al sesso, esempio: M=Maschio F=Femmina Cos' una registrazione Una registrazione, o record, un insieme di campi, ciascuno contenente dati di lunghezza fissa o variabile.
Nome e cognome ($) 1 A I A C E T E L A M O N I O | | | | | | | | | | | | | | | | | 25 | | | | | | | | |

Sesso Data di ($) nascita(*) 2627 3233

Luogo di nascita ($)

Matricola (#) 4546 50

| M| 2| 6| 0| 9| 5| 2| A| C| Q| U| A| V| I| V| A| (

| B| A| )| 1| 2| 3| 2| 3|

Dipartimento Ore ($) (#) 51 5657

Stipendio (#) 5960

Alt ( 6667

ezza Peso Campo #) (#) libero($) 6970 72 73 75

O R G V A L 3 5 1 5 0 0 0 0 0 1 7 2 | | | | | | | | | | | | | | | | | | | | |7 2 | | | | |

Campo libero ($) 76 80

| | | | | |

Figura 1.2: Esempio di record con campi a lunghezza fissa Nella figura 1.2, stato rappresentato un record avente lunghezza di 80 caratteri (o, come spesso si dice, di 80 bytes) suddiviso in 11 campi (10 contenenti dati ed 1 libero); ciascun campo caratterizzato da tre attributi: tipo di campo (#=numerico, $=alfanumerico, *=data); posizione iniziale del campo all'interno del record (es.: nel caso del campo contenente il luogo di nascita 33); 16

posizione finale del campo all'interno del record (es.: nel caso del campo contenente il luogo di nascita 45); lunghezza del campo, espressa in numero di caratteri esistenti dalla posizione iniziale del campo a quella finale (es.: nel caso del campo contenente il luogo di nascita 13). In generale un record potr contenere campi (dati) relativi allo stesso evento (esempio: dati fisici, anagrafici, contabili di un impiegato; dati relativi alle temperature massime registrate in ciascun mese dell'anno in una stazione climatica, ecc.). Cos' un archivio Un archivio, oppure data set o file, generalmente inteso come un insieme di registrazioni omogenee, cio che si riferiscono ad uno stesso soggetto o evento; esempio: l'insieme dei record rappresentanti ciascuno il Modello 101 di un contribuente, l'insieme dei record contenenti ciascuno i dati relativi ad un singolo dipendente di un'azienda, ecc.. Per quanto riguarda gli archivi SAS, invece dei nomi "campo" e "record", vengono usati rispettivamente i nomi: "variabile" ed "osservazione". Il concetto che i due nuovi nomi esprimono rimane comunque lo stesso come definito in precedenza. D'ora in avanti indicheremo con il nome di archivi "grezzi" quelli che non hanno formato SAS; tali archivi potranno essere fisicamente presenti (allocati) su supporti di natura diversa, come ad esempio: nella mente di un individuo; su un blocco notes; su di un supporto magnetico (es.: floppy disk); ecc.. Gli archivi in formato SAS, potranno essere allocati solo su supporti magnetici: dischi, nastri e floppy disk.

1.5. Come si presentano i problemi al Sistema SAS


La prima operazione da fare per presentare i nostri problemi al sistema SAS consiste nel suddividerli in passi (step) comprensibili al sistema. Un lavoro SAS consister di un qualsiasi numero di passi appartenenti a due soli tipi: 17

di creazione e modifica di archivi SAS, prelevando i dati da altri archivi SAS o da archivi grezzi (DATA step); di utilizzo di un archivio SAS (PROCedure step). Uno dei primi problemi in cui l'utente si imbatter, sar quello di individuare i dati da elaborare, di avere ben chiare le idee di cosa farne e di conoscerne l'organizzazione (formato delle registrazioni, distribuzione dei campi in ciascuna registrazione, attributi di ciascun campo, ecc.).

1.5.1. Come si scrivono i passi SAS


Un passo SAS si compone di dichiarazioni, ciascuna delle quali pu richiedere particolari elaborazioni (ad esempio: l'esecuzione di una operazione aritmetica, il richiamo di una funzione che genera numeri pseudo-casuali, il disegno di un grafico, la definizione di un modello di regressione, ecc.). Come regola sintattica di base bisogner ricordare che una dichiarazione si compone di parole di cui la prima, che viene chiamata parola chiave (keyword), serve per definire il tipo di operazione richiesta; una dichiarazione dovr terminare sempre con un carattere punto e virgola (;). A titolo d'esempio possiamo ipotizzare una situazione nella quale un docente intende utilizzare il sistema SAS per risolvere un problema di questo tipo: leggere i dati relativi agli studenti appartenenti alla sua classe (per ciascuno di essi sono riportati, oltre ai dati anagrafici, anche le votazioni relative agli esami sostenuti); determinare i valori medi delle votazioni. I dati sono annotati sul registro scolastico di fine anno nel quale ciascuna riga rappresenta un record contenente i dati anagrafici e di rendimento scolastico di ciascun soggetto, come mostrato in figura 1.3. Affinch il docente possa ottenere i risultati desiderati utilizzando un terminale, occorrer che egli digiti un programma SAS mediante il quale si istruisca l'elaboratore a creare un archivio contenente i dati di figura 1.3.

18

Nome Cognome Acerbi Anna Balloni Elena Bertini Claudio Garzella Eleonora Ghelardi Alberto Marini Sergio Mattei Diego Sorri Danilo Zerbini Raffaele Zurletti Alfio

Sesso F F M F M M M M M M

Et 15 15 16 15 15 16 14 15 16 15

Italiano Scritto 6 8 5 8 7 5 7 6 7 3

Latino Scritto 6 7 7 8 6 4 6 4 6 3

Figura 1.3: Registro di classe contenente i dati grezzi Per quanto concerne i dati, potremo considerare ogni riga inviata tramite tastiera, come il record relativo ad uno studente, contenente cio i suoi dati anagrafici e di profitto scolastico. Il docente dovr fornire all'elaboratore una serie di informazioni per aiutarlo nell'operazione di creazione dell'archivio SAS, che in seguito verr utilizzato per calcolare i valori medi delle votazioni. Alcune di queste informazioni riguarderanno: la scelta del nome che si intende dare al creando archivio; il futuro dell'archivio al termine della sessione di lavoro SAS: cio se esso dovr essere considerato permanente (e quindi conservato) o temporaneo (e quindi cancellato); l'inizio e la fine dei campi da leggere; il tipo di dati da leggere; i nomi da assegnare ai campi letti, in modo da rendere semplici le richieste di elaborazioni successive su di essi. Un esempio di programma in questione mostrato in figura 1.4. Con questo passo di DATA, verr creato un archivio SAS temporaneo di nome CLASSE. Detto archivio lo potremo immaginare come mostrato in figura 1.5, cio avente la forma di una tabella con un certo numero di righe (in questo caso, 10) e di colonne (5).

19

DATA

CLASSE; INPUT STUDENTE $ 1-30 SESSO $ 32 ETA 34-35 ITALIANO 37 LATINO 39; /*Il seguente commento evidenzia l'incolonnamento */ /* 11111111112222222222333333333344444444445*/ /*345678901234567890123456789012345678901234567890*/ CARDS; Acerbi Anna F 15 6 6 Balloni Elena F 15 8 7 Bertini Claudio M 16 5 7 Garzella Eleonora F 15 8 8 Ghelardi Alberto M 15 7 6 Marini Sergio M 16 5 4 Mattei Diego M 14 7 6 Sorri Danilo M 15 6 4 Zerbini Raffaele M 16 7 6 Zurletti Alfio M 15 3 3 ; /* <-------------- indicazione di fine dati */ RUN; /* <-------------- indicazione di fine passo */

Figura 1.4: Esempio di passo di creazione di un archivio SAS Come gi accennato in precedenza, le righe di una archivio SAS vengono definite osservazioni e, nel caso in questione, ogni osservazione corrisponder ad uno studente della classe.

N. 1 2 3 4 5 6 7 8 9 10

STUDENTE 1 Acerbi Anna Balloni Elena Bertini Claudio Garzella Eleonora Ghelardi Alberto Marini Sergio Mattei Diego Sorri Danilo Zerbini Raffaele Zurletti Alfio

SESSO 2 F F M F M M M M M M

ETA 3 15 15 16 15 15 16 14 15 16 15

ITALIANO 4 6 8 5 8 7 5 7 6 7 3

LATINO 5 6 7 7 8 6 4 6 4 6 3

Figura 1.5: Schema dell'archivio SAS CLASSE Ciascuna colonna viene definita variabile per il fatto che ciascun valore, all'incrocio di una riga e di una colonna scelta, pu variare in base al tipo di misura o di indicazione che la colonna rappresenta, es.: la variabile che rappresenta il sesso potr assumere al massimo due valori validi: M (maschio) oppure F (femmina) " 1 (maschio) 2 (femmina)

in base al fatto che decidiamo una codifica alfanumerica oppure numerica del dato. Ogni variabile dell'archivio dovr avere un nome che verr assegnato dall'utente, possibilmente in modo tale che da esso si possa facilmente risalire al contenuto della variabile (nome 20

mnemonico). Alle regole sintattiche che l'utente deve conoscere per assegnare correttamente i nomi alle variabili dedicato una parte del capitolo 2. Per quanto concerne l'esercizio in questione, baster sapere che le variabili in gioco sono: STUDENTE SESSO ETA ITALIANO LATINO e che nella dichiarazione INPUT, oltre ad elencare detti nomi, il docente dovr specificare, per ciascuno di essi, il relativo tipo, la posizione d'inizio e di fine del campo da leggere. Per esempio, si noter che il nome STUDENTE seguito da uno spazio, poi da un carattere $ (dollaro), indicante che il dato ha una codifica alfanumerica, ed infine dalla stringa 1-30 che indica al sistema SAS che il campo da leggere va dalla prima alla trentesima posizione nella riga dati relativa ad uno studente. Dopo la INPUT segue una dichiarazione CARDS che indica la fine della zona dichiarazioni e l'inizio della zona dati del programma; infatti dopo di essa seguono i dati da elaborare. Una volta scritto il passo di DATA, il docente potr richiamare due procedure gi esistenti nel sistema SAS che rispettivamente produrranno: la lista degli studenti dell'archivio creato; il valor medio di una o pi variabili (ad esempio ITALIANO e LATINO) dell'archivio in ingresso (CLASSE), semplicemente scrivendo:
PROC PRINT DATA=CLASSE; PROC MEANS DATA=CLASSE; VAR ITALIANO LATINO; RUN;

L'esecuzione di questi passi di PROCedure fornir al docente i risultati desiderati, come mostrato in figura 1.8. La figura 1.6 mostra come appare lo schermo del terminale quando si in ambiente SAS, in particolare durante la fase di digitazione del programma di figura 1.4, prima del suo invio in esecuzione. 21

NOTE: 27511, NOTE: NOTE:

COPYRIGHT (C) 1984,1986 SAS INSTITUTE INC., CARY, N.C. U.S.A. CMS SAS RELEASE 5.16 AT CNUCE (02483001). CPUID VERSION = FF SERIAL = 001964 MODEL = 3081 .

Versione del SAS 5.16 installata il 9/MAR/87 Per ulteriori informazioni dare il comando HELP NEWS in ambiente SAS. -----------------------------------------------------------------Command ===> Program Editor 00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 DATA CLASSE; INPUT STUDENTE $ 1-30 SESSO $ ITALIANO 37 LATINO 39; CARDS; Acerbi Anna F 15 Balloni Elena F 15 Bertini Claudio M 16 Garzella Eleonora F 15 Ghelardi Alberto M 15 Marini Sergio M 16 Mattei Diego M 14 Sorri Danilo M 15 Zerbini Raffaele M 16 Zurletti Alfio M 15

32 ETA 34-35

6 8 5 8 7 5 7 6 7 3

6 7 7 8 6 4 6 4 6 3

Figura 1.6: Esempio d'uso del Display Manager System per digitare un programma La figura 1.7 mostra i messaggi che il sistema SAS invia al termine dell'esecuzione dei passi di programma in oggetto.

Command ===>

SAS(r) Log

15:28

1 DATA CLASSE; 2 INPUT STUDENTE $ 1-30 SESSO $ 32 ETA 34-35 3 ITALIANO 37 LATINO 39; 4 CARDS; NOTE: DATA SET WORK.CLASSE HAS 10 OBSERVATIONS AND 5 VARIABLES. 15 ; 16 PROC PRINT DATA=CLASSE; 17 PROC MEANS DATA=CLASSE; 18 VAR ITALIANO LATINO; 19 RUN; ----------------------------------------------------------------Command ===> Program Editor 00001

Figura 1.7: Esempio di messaggi e note SAS inviate sull'area di Log(SASLOG)

22

OBS STUDENTE 1 2 3 4 5 6 7 8 9 10 Acerbi Anna Balloni Elena Bertini Claudio Garzella Eleonora Ghelardi Alberto Marini Sergio Mattei Diego Sorri Danilo Zerbini Raffaele Zurletti Alfio

SESSO ETA ITALIANO LATINO F F M F M M M M M M 15 15 16 15 15 16 14 15 16 15 6 8 5 8 7 5 7 6 7 3 6 7 7 8 6 4 6 4 6 3

VARIABLE

MEAN

STANDARD DEVIATION 1.54919334 1.56702124

MINIMUM VALUE 3.00000000 3.00000000

MAXIMUM VALUE

STD ERROR OF MEAN

ITALIANO LATINO

10 10

6.20000000 5.70000000

8.00000000 0.48989795 8.00000000 0.49553562

Figura 1.8: Esempi di risultati prodotti da procedure SAS sull'area di Output (Proc Print e Proc Means)

1.5.2. Come si sottomettono i passi al sistema SAS


Come specificato in precedenza, il sistema SAS pu operare (essere "ospitato") su diversi calcolatori ciascuno dei quali sar dotato di un proprio sistema operativo, cio quella parte del software di base che ha il compito di controllare tutte le attivit della macchina, incluso quelle relative ai sistemi applicativi loro ospiti (es.: SAS). Esistono sistemi operativi che, per la loro natura, permettono diversi "modi di esecuzione dei programmi" ad essi sottomessi; in funzione di questi modi di operare, tali sistemi operativi vengono classificati in: batch; interattivi (o conversazionali); Un sistema operativo batch permette l'esecuzione contemporanea di lavori (job) da parte di utenti differenti ma, dal momento della loro sottomissione sino al ricevimento dei relativi risultati (output), ciascun utente non in grado di interagire direttamente con il proprio lavoro. Il tempo che intercorre tra la sottomissione di un job ed il ricevimento del relativo output viene definito come "tempo di ritorno del job" (job turnaround time); detto tempo pu variare da qualche secondo a qualche ora e, per lavori molti grandi, l'utente potr addirittura attendere i risultati per giorni interi. 23

Un sistema operativo interattivo permette lo stabilirsi di una comunicazione diretta tra l'utente e l'elaboratore; il primo invier comandi opportuni alla macchina per mezzo di un dispositivo di ingresso (input device) quale, ad esempio, la tastiera di un terminale oppure di oggetti di pi semplice uso (o come di dice in gergo: pi user friendly ) come, ad esempio, il mouse. Il sistema analizzer i comandi ricevuti verificandone la correttezza formale e, se non riscontra errori, li eseguir visualizzando i risultati su di un dispositivo di output (output device) come, ad esempio, il video di un terminale. Appare evidente che se l'utente desidera interagire maggiormente con l'elaboratore (cio desidera un tempo di risposta alle sue domande alquanto breve), dovr usare un elaboratore dotato di sistema operativo conversazionale. La scelta del sistema operativo influisce direttamente sul modo di lavorare con il sistema SAS; infatti un elaboratore dotato di un sistema operativo strettamente batch, non potr ospitare il sistema SAS in maniera interattiva ( il sistema operativo ospitante che stabilisce le regole del gioco). Tenendo presente questo vincolo, l'utente invitato, prima di cominciare a lavorare con il sistema SAS, a chiedere informazioni al responsabile del sistema informatico del proprio ente circa i modi possibili di lavorare ed eventuali limitazioni derivanti da fattori organizzativi aziendali. Con il sistema SAS possibile lavorare in tre modi distinti: interattivo; batch; semi-interattivo.

1.5.2.1.

Modo interattivo

Il primo modo consiste nell'attivare una sessione di lavoro SAS mediante l'invio di un apposito comando (generalmente esso : SAS). Da quel momento in poi sar possibile digitare i programmi utilizzando il linguaggio SAS, ottenendo i risultati immediatamente sul video del terminale. Per terminare la sessione di lavoro (uscire dal sistema SAS) l'utente dovr digitare un apposito comando del tipo: BYE, ENDSAS o /*, in funzione del modo di lavorare scelto, come si dir pi avanti. Il modo con cui una sessione interattiva pu essere attivata dipende anche dal tipo di terminale che l'utente ha a disposizione; in particolare esistono due classi di dispositivi: 24

terminali linea dopo linea (line by line); terminali a video pieno (full-screen). Una sessione di lavoro, attivata tramite un terminale del primo tipo, si svolger in questo modo: l'utente digiter le dichiarazioni SAS una dopo l'altra; su ogni dichiarazione ricevuta, il sistema SAS eseguir controlli di validit sintattica ( scritta bene?) e semantica (ha un senso?); nel caso di errori, essi verranno immediatamente segnalati sul video; in mancanza di errori, il sistema SAS eseguir i comandi ricevuti sino ad allora solo quando verr digitata la dichiarazione "RUN;". Sia i messaggi di errore che il risultato dell'elaborazione richiesta (es.: un istogramma), compariranno sul video inframmezzati alle dichiarazioni SAS che li hanno prodotti. In questo modo, il video simula un foglio di carta infinito e, data la finitezza dello schermo (in genere 24 o 32 righe di 80 caratteri ciascuna), su di esso compariranno solo le informazioni pi "fresche", e via via che lo schermo si riempie, le linee pi vecchie scompariranno verso l'alto. Se l'utente ha un terminale full-screen possibile lavorare con il sistema SAS usando il "SAS Display Manager System" (SAS DMS), introdotto a partire dalla versione 5 del prodotto. Il DMS suddivide lo schermo del terminale in finestre (window) differenti, in modo tale che risultino chiaramente distinti i programmi SAS, i messaggi di errore ed i risultati delle elaborazioni, come mostrato nelle figure 1.6, 1.7 e 1.8. Per una pi completa trattazione dei comandi e delle possibilit offerte dal SAS DMS, si rimanda il lettore all'appendice A.

1.5.2.2.

Modo Batch

Questo ambiente di lavoro certamente pi ostico del precedente, in quanto risulta maggiore l'interazione fra utente e sistema operativo ospitante. Infatti, in generale, un lavoro da inviare al sistema SAS in batch dovr essere composto, oltre che dai passi SAS veri e propri, anche da una serie di ulteriori informazioni per il sistema operativo che serviranno per: identificare il lavoro in questione riportando, ad esempio, dati come: il nome del job, il codice di addebito, il nome del programmatore, il tempo di esecuzione previsto, il numero di righe di stampa 25

previste, ecc.; richiamare il compilatore del linguaggio usato per scrivere i programmi (nel nostro caso occorrer indicare: SAS); indicare gli eventuali archivi in ingresso e/o in uscita che verranno trattati nel corso del programma. Dette informazioni vengono inviate al sistema operativo utilizzando un particolare linguaggio che, ad esempio, in ambiente IBM con sistema operativo MVS, viene definito Job Control Language (JCL). Tutti i lavori batch dovranno essere preceduti da comandi di JCL, come schematizzato nella figura 1.9, che mostra un esempio di programma SAS in ambiente MVS:
//LAVSAS JOB (H001,F045,01,0020), 'AIACE TELAMONIO' // EXEC SAS //*la prossima riga definisce la locazione fisica dello //*archivio in cui sono memorizzati i dati di ingresso //ALUNNI DD DSN=ESEMPIO.A1987.DATI(CLASSE3B), DISP=SHR //SYSIN DD * DATA CLASSE; /*la prossima dichiarazione "punta" ai dati da leggere per mezzo del nome convenzionale ALUNNI */ INFILE ALUNNI; INPUT STUDENTE $ 1-30 SESSO $ 32 ETA 34-35 ITALIANO 37 LATINO 39; PROC PRINT DATA=CLASSE; PROC MEANS DATA=CLASSE; VAR ITALIANO LATINO; RUN; //

Figura 1.9: Esempio di lavoro SAS da eseguire in batch

1.5.2.3.

Modo semi-interattivo

Per lavorare in modo semi-interattivo, necessario che l'utente abbia in precedenza preparato un archivio contenente le dichiarazioni SAS e gli eventuali dati da elaborare, utilizzando le possibilit offerte da un programma "editore" (text editor program) generalmente fornito di corredo all'elaboratore assieme al sistema operativo. Un text editor accetta un insieme di comandi che permettono la digitazione di testi di qualunque natura (es.: le dichiarazioni in un qualsiasi linguaggio, i dati da elaborare, ecc.), la loro modifica futura, nonch la possibilit di memorizzarli o cancellarli a richiesta. Mediante l'uso di detto strumento l'utente potr creare 26

un archivio, contenente programmi e dati, ed inviarlo al sistema SAS restando nel proprio ambiente operativo (TSO o CMS, ad esempio). In generale, dipendendo dal sistema operativo in questione, l'utente dovr inviare un comando del tipo: SAS <specifiche del file precedentemente creato> ad esempio, sotto VM/CMS, se stato creato un file CMS avente nome "PROGR01" e tipo "SAS", occorrer inviare il seguente comando: SAS PROGR01 a seguito del quale, il sistema SAS produrr i seguenti files su disco: PROGR01 LISTING (contenente i risultati delle elaborazioni); PROGR01 SASLOG (contenente informazioni relative al programma SAS eseguito, ed in particolare la lista degli eventuali errori). Detti files potranno in seguito essere stampati con comandi opportuni. Aggiungendo ulteriori informazioni sar possibile passare, a richiesta, eventuali opzioni di personalizzazione del funzionamento del SAS, valide per la sola durata del lavoro in questione. Ad esempio, inviando il seguente comando: SAS PROGR01 (CENTER si chieder al sistema SAS di centrare i risultati prodotti dal programma PROGR01 all'interno di ciascuna pagina di stampa. Quando conviene lavorare in interattivo e quando in batch In generale si consiglia di lavorare interattivamente quando: si desidera una maggiore interazione con l'elaboratore; ci sono pochi dati da elaborare; si scrivono e si mettono a punto i programmi. Alternativamente, si consiglia di lavorare in batch quando: i tempi di risposta non rappresentano un vincolo (possiamo, ad esempio, permetterci di ritirare i risultati anche il giorno dopo ...); i dati da elaborare sono molti (si pensi, ad esempio, a 10 bobine di nastro contenenti dati di un censimento); 27

la fase di scrittura e messa a punto delle applicazioni terminata ed i programmi richiedono un elevato tempo di elaborazione (si pensi, ad esempio, all'esecuzione notturna di particolari programmi, sfruttando periodi nei quali gli elaboratori sono usualmente pi scarichi di lavori).

28

2. Il passo di DATA

2.1.

Struttura degli archivi SAS

Immaginiamo di dover eseguire alcune elaborazioni sui dati riguardanti gli abitanti di un certo comune. I primi problemi da risolvere saranno la definizione dei dati da analizzare per ogni abitante che vogliamo considerare nella nostra elaborazione, la loro raccolta e la loro memorizzazione su di un supporto adatto ad essere utilizzato da un elaboratore di dati. Supponiamo allora che per la nostra ipotetica elaborazione serva registrare per ogni abitante il nome, il cognome, la data di nascita, il sesso, il reddito, il numero di figli ed il titolo di studio. In figura 2.1 sono riportati alcuni dati che potrebbero rappresentare quelli relativi agli abitanti che ci interessano.
N 1 2 3 4 5 6 7 8 9 10 11 NOME COGNOME NATO_IL 16/10/1952 15/08/1975 15/08/1950 12/03/1942 26/02/1954 27/05/1957 22/11/1960 11/05/1956 15/08/1965 12/08/1962 5/08/1946 SESSO M M M M M F F F F M M REDDITO 32.000.000 0 27.000.000 95.000.000 35.000.000 40.000.000 80.000.000 25.000.000 36.000.000 35.000.000 FIGLI 1 0 1 0 3 0 5 2 2 1 1 TITOLO 1 2 1 4 2 1 0 2 3 1 1

Mario Aloia Marco Bianchi Elia Biorci Walter Chiari Guido Fusi Ada Mori Anna Neri Gina Rossi Licia Saba Enzo Verdi Guido Zini

Figura 2.1: Prospetto contenente i dati da elaborare Nel sistema SAS le righe della tabella di figura 2.1 vengono chiamate Osservazioni e le colonne vengono chiamate variabili. Quando si vuol individuare un dato in modo preciso possiamo utilizzare il numero dell'osservazione e l'intestazione della colonna alla quale ci si riferisce. Si dice quindi che il valore della variabile COGNOME della settima osservazione " Neri" e il REDDITO della quarta osservazione 95.000.000. Osservando la tabella possiamo notare che alcuni valori relativi al reddito sono mancanti. 29

Evidentemente nel raccogliere i dati non abbiamo potuto rintracciare alcuni valori o nel compilare la tabella abbiamo erroneamente lasciato il posto in bianco. Usando la terminologia SAS si dir che il valore della variabile REDDITO della undicesima osservazione mancante ovvero che la variabile REDDITO della undicesima osservazione assume valore mancante. Non si deve confondere il valore mancante (REDDITO dell'undicesima osservazione) con 0 (REDDITO della seconda osservazione). Nel sistema SAS i "valori mancanti" sono valori che nelle elaborazioni sono trattati in modo particolare, ma vengono registrati negli archivi come gli altri valori. Una volta individuati e raccolti i dati da elaborare ci dobbiamo preoccupare di registrarli su di un supporto che l'elaboratore possa utilizzare. I supporti pi comunemente usati sono i dischi magnetici (siano essi dischi flessibili o rigidi) e i nastri magnetici. I dati vengono organizzati sui supporti in modi diversi, che dipendono dai sistemi utilizzati per scriverli. Il sistema SAS pu utilizzare tutti i tipi di organizzazione pi comuni per la memorizzazione dei dati. Esso ci offre inoltre la possibilit di utilizzare un suo tipo di organizzazione che risulta molto conveniente per elaborazioni successive con il sistema SAS stesso. Negli archivi SAS (nel seguito per archivio SAS intenderemo un archivio che utilizza l'organizzazione del sistema SAS) i dati vengono memorizzati rispettando la disposizione in osservazioni e variabili esattamente come nella tabella di figura 2.1. Anche i valori vuoti vengono registrati, cos che i dati di un archivio SAS assumono in uscita sempre un aspetto rettangolare. Le righe e le colonne rappresentano rispettivamente le osservazioni e le variabili. Per poter individuare le colonne (variabili) dovremo stabilire i nomi di ciascuna variabile. I nomi delle variabili possono essere scelti dall'utilizzatore del sistema SAS rispettando le regole elencate di seguito: devono essere composti da lettere dell'alfabeto inglese (maiuscolo o minuscolo non fa differenza), cifre numeriche e il carattere speciale "_ " (sottolineato); non possono superare la lunghezza di otto caratteri; devono iniziare con una lettera dell'alfabeto o con il carattere speciale "_", ma non con una cifra numerica. Alcuni esempi di nomi di variabili che possiamo utilizzare sono: NOME, COGNOME, SESSO, NATO_IL, REDDITO, FIGLI, TITOLO, ABCD, NUMERO, DATO1, DATO2, DATO_1, ... I nomi: Abc, aBc, ABC, ... risulteranno equivalenti; risulteranno errati i nomi di variabili come: 1ABC (non deve cominciare per cifra numerica), DATO-1 (non deve contenere caratteri speciali 30

come il trattino), Et (non deve contenere caratteri speciali come l'accento), DIPLOMATO_IL (non deve superare gli otto caratteri ). Una ulteriore regola consigliata dal buon senso, ma non categorica, quella di scegliere nomi di variabili significativi e comprensibili evitando di assegnare alle variabili sigle complicate o nomi non attinenti ai dati da trattare. Quanto risulterebbero comprensibili i dati di figura 2.1 se fossero stati scritti come nelle tabelle di figura 2.2 o di figura 2.3 ?
N 1 2 3 4 5 6 7 8 9 10 11 VAR1 Mario Marco Elia VAR2 Aloia Bianchi Biorci VAR3 16/10/1952 15/08/1975 15/08/1950 12/03/1942 26/02/1954 27/05/1957 22/11/1960 11/05/1956 15/08/1965 12/08/1962 5/08/1946 VAR4 M M M M M F F F F M M VAR5 32.000.000 0 27.000.000 95.000.000 35.000.000 40.000.000 80.000.000 25.000.000 36.000.000 35.000.000 VAR6 1 0 1 0 3 0 5 2 2 1 1 VAR7 1 2 1 4 2 1 0 2 3 1 1

Walter Chiari Guido Ada Anna Gina Licia Enzo Guido Fusi Mori Neri Rossi Saba Verdi Zini

Figura 2.2: Esempio di cattivo uso dei nomi delle variabili Le regole del sistema SAS sono state rispettate anche in queste due tabelle che per risultano incomprensibili senza una spiegazione.
N 1 2 3 4 5 6 7 8 9 10 11 BARI Mario Marco Elia SIENA Aloia Bianchi Biorci GENOVA 16/10/1952 15/08/1975 15/08/1950 12/03/1942 26/02/1954 27/05/1957 22/11/1960 11/05/1956 15/08/1965 12/08/1962 5/08/1946 PISA M M M M M F F F F M M FIRENZE 32.000.000 0 27.000.000 95.000.000 35.000.000 40.000.000 80.000.000 25.000.000 35.000.000 35.000.000 ASTI 1 0 1 0 3 0 5 2 2 1 1 ROMA 1 2 1 4 2 1 0 2 3 1 1

Walter Chiari Guido Ada Anna Gina Licia Enzo Guido Fusi Mori Neri Rossi Saba Verdi Zini

Figura 2.3: Un altro esempio di cattivo uso dei nomi delle variabili Assumiamo quindi i nomi utilizzati per intestare la tabella di figura 2.1 come nomi di variabili SAS. In questa tabella si possono distinguere due tipi di variabili: quelle "numeriche", cio quelle i 31

cui valori possono essere utilizzati in operazioni aritmetiche (REDDITO, TITOLO, FIGLI) e quelle "non numeriche" i cui valori non possono venire impiegati in calcoli (NOME, COGNOME, SESSO e NATO_IL). Anche il sistema SAS distingue i tipi di variabili e quando gli forniamo dati dovremo segnalare quali sono secondo noi le variabili da utilizzare per fare conti e quali no. Normalmente la scelta ovvia, ma ci sono alcuni casi in cui siamo indecisi se il valore di una variabile sia da considerarsi numerico o no. Il numero di matricola o la partita IVA, ad esempio, pur se rappresentabili con numeri, non sono utilizzabili per calcoli. Oltre a ci, le variabili numeriche differiscono principalmente dalle variabili non numeriche per lo spazio che occupano sia su disco magnetico, quando vengono registrate, sia nella memoria centrale dell'elaboratore, quando vengono utilizzate, a causa del tipo di codifica adottato per la memorizzazione. Le variabili numeriche occupano sempre (salvo rare eccezioni di cui parleremo nel seguito) 8 posizioni di memoria (8 bytes o caratteri). In 8 posizioni vengono registrati numeri indipendentemente dalla loro grandezza, sia che abbiano poche cifre sia che abbiano molte cifre (possono essere pi di otto cifre). Esiste un limite alla grandezza del numero da elaborare, che dipende dal tipo di elaboratore utilizzato. Tale limite risulta essere per solo teorico perch gli elaboratori normalmente possono trattare numeri talmente grossi che nella pratica non vengono mai superati. Le variabili non numeriche possono avere una lunghezza compresa tra 1 e 200 posizioni di memoria. Il sistema SAS attribuir la lunghezza ad ogni variabile non numerica definita in un programma prelevando le informazioni, implicite o esplicite, dal contesto del programma stesso. Il sistema SAS prevede che nei suoi archivi vengano registrati, oltre ai valori delle variabili che costituiscono i dati veri e propri, anche alcune informazioni sull'archivio stesso come le caratteristiche delle variabili (il nome, il tipo, la lunghezza prevista, ecc.), il numero totale di osservazione, la data di creazione dell'archivio, la storia delle modifiche effettuate, il testo del programma che ha creato l'archivio SAS, ecc. Questi dati informativi vengono registrati in una parte apposita dell'archivio SAS, detta parte descrittiva dellarchivio (o descrittore) che si distingue dalla parte dati che contiene i valori dei dati veri e propri. In figura 2.4 mostrato schematicamente un archivio SAS. Nella figura vengono anche indicate le principali procedure che permettono la visualizzazione di un archivio SAS su tabulato, la PROC PRINT e la PROC CONTENTS, o direttamente su video, la PROC FSEDIT e la PROC DATASETS. Maggiori dettagli su alcune di queste procedure verranno dati nei capitoli seguenti. La documentazione contenuta nella parte descrittiva sar utile 32

sia al programmatore, che la sfrutter per avere un documento completo e di formato standard sulle caratteristiche dei dati contenuti nell'archivio, sia all'utente finale che potr utilizzare in modo semplice archivi creati da altre persone, sia infine al sistema SAS stesso che, utilizzando queste informazioni, consentir di ridurre drasticamente la codifica delle specifiche (necessarie nei linguaggi di programmazione tradizionali) relative alle variabili contenute in un archivio SAS.
PROC CONTENTS
DESCRITTORE

PROC DATASETS

DATI

PROC DATASETS PROC FSEDIT PROC PRINT

Figura 2.4: Alcune PROC che permettono di visualizzare un archivio SAS

2.2.

Creazione di un archivio SAS

Viene riportato in figura 2.5 un semplice programma che, a partire da dati "grezzi", crea un archivio SAS e lo stampa. Possiamo subito distinguere nel programma due parti, o, pi tecnicamente, passi (step): il primo crea un archivio SAS di nome "ANAGRAFE" partendo dai dati grezzi; esso comincia con la parola "DATA..." e finisce con la parola "RUN;". Il secondo, il passo PROCEDURE (detto di solito PROC) stampa i dati contenuti nell'archivio SAS di nome "ANAGRAFE"; esso comincia con la parola "PROC..." e finisce con la parola "RUN;". Pi in generale nel sistema SAS si tende a suddividere un problema complesso in pi problemi elementari ciascuno dei quali viene risolto da un passo di programma SAS. I tipi di passo previsti sono solo due: il passo di DATA e il passo PROCEDURE o PROC. Nel primo tipo di passo possiamo utilizzare strumenti di 33

programmazione analoghi a quelli messi a disposizione da un linguaggio di programmazione ad alto livello. Con il passo di PROC si richiamano procedure gi confezionate che abbreviano il lavoro di programmazione, incrementando la produttivit individuale, e permettono la risoluzione di problemi anche complessi da parte di persone che non siano esperti programmatori. Normalmente i passi di DATA servono a predisporre l'archivio SAS pi adatto ad essere elaborato successivamente dai vari passi PROC richiamati. La maggior parte delle procedure esistenti infatti, in grado di lavorare solo su dati organizzati in maniera SAS.
DATA ANAGRAFE; INPUT

NOME $ 1-8 COGNOME $ 10-18 NATO_IL $ 21-30 SESSO $ 34 REDDITO 37-45 FIGLI 49-50 TITOLO 53-54; M M M M M F F F F M M 32.000.000 0 27.000.000 95.000.000 35.000.000 40.000.000 80.000.000 25.000.000 36.500.000 35.000.000 15.000.000 1 0 1 0 3 0 5 2 2 1 1 1 2 1 4 2 1 0 2 3 1 1

CARDS; Mario Aloia 16/10/1952 Marco Bianchi 15/08/1975 Elia Biorci 15/08/1950 Walter Chiari 12/03/1942 Guido Fusi 26/02/1954 Ada Mori 27/05/1957 Anna Neri 22/11/1960 Gina Rossi 11/05/1956 Licia Saba 15/08/1965 Enzo Verdi 12/08/1962 Guido Zini 5/08/1946 RUN; PROC PRINT DATA=ANAGRAFE; RUN;

Figura 2.5: Esempio di creazione di un archivio SAS e relativa stampa Soffermiamoci a questo punto ad esaminare pi in dettaglio il passo di DATA dell'esempio di figura 2.5. Esso composto da tre parti, separate tra loro da un punto e virgola, dette dichiarazioni o statement (in certa letteratura si usa il termine istruzione). I dati non vengono considerati come facenti parte del programma: vengono allegati in coda al passo di DATA che li dovr considerare. Le regole di scrittura delle dichiarazioni sono riportate di seguito: possono iniziare in una qualunque posizione della riga; possono terminare in una qualunque posizione della riga; possono continuare su pi righe e pi istruzioni possono stare su di una sola riga; quando sono composte da pi parole, queste devono essere separate da almeno uno spazio, se non sono gi separate da altri caratteri che fungono da separatore (es.: "; +-* / ="). Dalle regole sopra riportate si pu notare come il formato delle 34

istruzioni sia completamente libero, ma per una pi facile lettura da parte nostra conveniente osservare alcuni elementari accorgimenti. Come si pu notare dall'esempio, si cercato di evitare di scrivere pi istruzioni per riga e di seguire un particolare incolonnamento. Allineando sul margine sinistro solo le parole "DATA" "PROC" e RUN abbiamo evidenziato la struttura dei passi. Le parole "DATA" e "PROC" sono infatti quelle che indicano rispettivamente l'inizio di un passo DATA e di un passo di PROC. La parola RUN indica invece la fine di un passo. Non sempre necessario indicare la fine dei passi, perch il sistema SAS considera concluso uno step ogni volta che trova l'inizio di uno successivo o quando trova la fine del programma. Tutte le istruzioni che fanno parte di uno step vengono scritte allineate tra loro un po' pi a destra. Se una dichiarazione non termina in una riga, la continuazione viene incolonnata, nella riga successiva, ancora pi a destra. Esaminiamo ora il significato delle dichiarazioni scritte nel programma dell'esempio di figura 2.5. Iniziamo con il passo di DATA, rimandando al prossimo capitolo il passo di PROC. La prima dichiarazione, DATA, indica linizio ed il tipo di passo e larchivio SAS che verr creato. Questa dichiarazione non specifica una azione da eseguire, ma fornisce solo alcune indicazioni al sistema SAS. Anche la dichiarazione CARDS non indica nessuna azione: ha infatti come unico scopo quello di indicare che il passo concluso per quanto riguarda le dichiarazioni, e dalla successiva riga cominciano i dati. L'unica dichiarazione che indica una azione vera e propria INPUT. Essa infatti indica l'azione di lettura dei dati: i dati, cio, verranno prelevati e portati nella memoria centrale dell'elaboratore subendo le conversioni e modifiche previste dal sistema SAS. Per spiegare il funzionamento del sistema SAS, quando si trova a dover elaborare il passo di DATA dell'esempio, occorre fare una breve digressione sui compilatori e sugli interpreti. Per brevit alcuni concetti fondamentali vengono solo accennati, in modo incompleto, quanto basta per una buona comprensione del linguaggio SAS. Gli elaboratori elettronici sono predisposti per poter eseguire un certo insieme di istruzioni che varia da tipo a tipo di elaboratore. L'insieme delle istruzioni "comprensibili" ad un certo elaboratore viene chiamato il "linguaggio macchina di quell'elaboratore. Bench sia possibile scrivere programmi utilizzando il linguaggio macchina, al giorno d'oggi nessuno usa pi questa tecnica (i pionieri dell'elaborazione elettronica trovavano normale utilizzare direttamente il linguaggio macchina). Si preferisce utilizzare altri linguaggi, detti linguaggi evoluti (ad alto livello), che verranno poi convertiti da un traduttore (che altro non che un programma in 35

linguaggio macchina) prima di essere eseguiti dall'elaboratore. Di seguito si citano le principali ragioni che hanno fatto s che questa tecnica prendesse piede. Il linguaggio macchina normalmente molto difficile da utilizzare anche perch prevede una conoscenza approfondita dell'organizzazione della macchina e le istruzioni sono state studiate per essere facilmente utilizzate da un elaboratore e non da una persona. Inoltre le operazioni che eseguono gli elaboratori sono piuttosto elementari e la scrittura di un programma in linguaggio macchina risulta molto lunga e richiede una notevole pazienza e perdita di tempo. Poich ogni tipo di elaboratore ha un diverso linguaggio macchina, nel caso di una sua sostituzione con un altro non compatibile, dovremmo imparare da capo un nuovo linguaggio, e conseguentemente modificare tutti i programmi scritti fino ad allora. I moderni linguaggi sono invece studiati in modo tale che risultino: di facile comprensione per l'uomo; le dichiarazioni sono composte da parole che hanno un senso per minimizzare lo sforzo mnemonico dell'utilizzatore; portabili: in modo che sia possibile trasferire programmi su vari modelli di elaboratori dovendo sostituire solo il traduttore. Tale caratteristica oggi divenuta indispensabile a causa del continuo ed incalzante succedersi di nuovi modelli; se i programmi non fossero portabili, moltissimo lavoro andrebbe sprecato nell'adattare in continuazione i programmi agli ultimi modelli; sintetici: tali da permettere la scrittura di programmi, anche complessi, con poche istruzioni. I linguaggi moderni sono considerati tanto pi evoluti quanto pi rispondono a criteri del tipo di quelli sopra esposti. Per quanto riguarda la traduzione da un programma scritto in linguaggio ad alto livello, nell'equivalente versione in linguaggio macchina, esistono principalmente due tecniche che prevedono l'uso di compilatori o interpreti. I compilatori sono strumenti software che leggono il nostro programma in linguaggio evoluto e producono un programma equivalente scritto in linguaggio macchina: una vera e propria traduzione. Gli interpreti invece sono programmi in grado di effettuare tutte le azioni che possono essere specificate dal linguaggio che si vuole interpretare; scorrendo il programma scritto dall'utente essi individuano (interpretano) ogni azione richiesta e la eseguono. Esistono vantaggi e svantaggi per ambedue le tecniche; cercheremo di dare un'idea delle problematiche con alcune 36

considerazioni. Il compilatore generalmente pi complicato da utilizzare: dovremo infatti farlo eseguire per ottenere la traduzione e produrre un programma equivalente in linguaggio macchina. Successivamente, per ottenere i risultati richiesti, dovremo far eseguire la versione tradotta. Con l'interprete invece, fornendo il programma riceveremo subito i risultati. Per la messa a punto dei programmi gli interpreti sono favoriti perch spesso permettono di effettuare correzioni al momento in cui ci accorgiamo di eventuali errori, per poi proseguire nell'esecuzione. Con il compilatore invece, quando necessario correggere errori presenti nel programma, dobbiamo ricominciare dalla fase di traduzione. Anche nel caso di errori in fase di esecuzione, il compilatore risulta svantaggiato; mentre l'interprete, lavorando direttamente sul programma scritto da noi (detto programma sorgente), pu segnalarci esattamente il punto in cui si verificato l'errore, il compilatore rintraccia facilmente la dichiarazione errata del programma tradotto, che per non risulta molto significativa per chi ha scritto il programma. L'indicazione della dichiarazione del programma sorgente che ha causato l'errore, talvolta avviene in modo indiretto e poco comprensibile. In passato per molti linguaggi sono stati costruiti sia il compilatore che l'interprete. Il programma veniva messo a punto con l'interprete e poi messo in produzione tradotto da un compilatore. Infatti, una volta corretto un programma, la sua versione compilata decisamente pi veloce di quella interpretata. E' questo il caso di linguaggi quale il FORTRAN, il PL/I, il BASIC, il PROLOG, il PASCAL e molti altri. In tempi pi recenti sono stati introdotti compilatori molto veloci che non penalizzano la fase di prova di un programma e anzi mettono a disposizione strumenti che facilitano la messa a punto. Un esempio di tali linguaggi dato dal Turbo Prolog, Turbo Pascal, Quick Basic e dal sistema SAS. Il sistema SAS dotato di un compilatore, ma i tempi di compilazione sono talmente veloci e le segnalazioni degli errori talmente precise che durante la messa a punto dei programmi non ci accorgiamo di avere a che fare con un compilatore. I due paragrafi seguenti sono molto importanti, perch mostrano in dettaglio cosa avviene "dietro le quinte" durante le fasi di compilazione e di esecuzione di un passo il DATA.

2.3.

La compilazione del passo di DATA

Il sistema SAS ha bisogno di due fasi per fornire i risultati richiesti da un passo di DATA: la compilazione e lesecuzione. Questo ciclo in due fasi tipico sia del passo di DATA che di PROC; limi37

tiamoci qui a considerare il passo di DATA. Nella fase di compilazione il sistema SAS, oltre a tradurre il linguaggio come detto sopra, fa anche altre azioni importanti. Consideriamo, ad esempio, il passo di DATA presentato nell'esempio di figura 2.5. Esso ha necessit, durante la fase di esecuzione, di leggere dati grezzi; cio deve scandire le righe di dati riportati dopo la parola CARDS per individuare i valori delle variabili SAS. A questo scopo, in fase di compilazione, il sistema SAS riserva nella memoria centrale un numero di bytes pari al numero di posizioni (battute) della riga dati. La memoria cos riservata prende il nome di input buffer, (vedere figura 2.6).

INPUT BUFFER
NOME COGNOME NATO_IL SESSO REDDITO FIGLI TITOLO

VETTORE DEI DATI (PDV)

# Valore numerico $ Valore non numerico

ARCHIVIO SAS

DESCRITTORE DATI

Figura 2.6: Aree di memoria necessarie durante la compilazione Nel nostro caso, dalla presenza della dichiarazione CARDS, possiamo dedurre che i dati sono stati scritti mediante l'uso di un terminale o mediante l'uso di un personal computer. In tutti e due i casi sono previste sullo schermo righe di 80 colonne come massima lunghezza. L'input buffer conterr quindi 80 posizioni. Se i dati, invece di essere stati riportati all'interno di un programma, si trovassero in archivi grezzi con lunghezza riga organizzati in record di lunghezza diversa da 80 posizioni, l'input buffer sarebbe dimensionato diversamente. Nel passo di DATA dell'esempio di figura 2.5 utilizziamo sette variabili SAS. In fase di compilazione il sistema SAS riserva l'opportuno spazio nella memoria centrale dell'elaboratore per contenere i valori di tutte le variabili. Tale spazio, detto vettore dei 38

dati del programma, indicato normalmente con la sigla PDV dallinglese Program Data Vector viene riservato uno spazio di dimensioni opportune. Le variabili occupano sempre, salvo esplicita indicazione, otto posizioni come spiegato precedentemente. Le variabili non numeriche, invece, occupano un numero di posizioni che dipendono da come sono state definite. Nell'esempio di figura 2.5 le variabili appartenenti al PDV saranno:
NOME COGNOME NATO_IL SESSO REDDITO FIGLI TITOLO

Variabile non numerica di 8 posizioni Variabile non numerica di 9 posizioni Variabile non numerica di 10 posizioni Variabile non numerica di 1 posizione Variabile numerica di 8 posizioni Variabile numerica di 8 posizioni Variabile numerica di 8 posizioni

Nella dichiarazione INPUT, le variabili non numeriche sono indicate con $ (simbolo dollaro) e ogni variabile seguita dalla colonna di inizio campo e di fine campo entro cui si trova il valore da attribuire a quella variabile. Per la variabile NOME troviamo le specifiche "$ 1-8" indicanti che la variabile NOME di tipo non numerico e si trova nei dati in un campo che occupa le colonne da 1 a 8. Nel PDV verranno quindi allocati per la variabile NOME 8 caratteri, e non sar pertanto possibile assegnare ad essa valori che superino gli 8 caratteri (essi verrebbero troncati a destra). Analogo ragionamento pu essere fatto per la variabile COGNOME che ha le specifiche "$ 10-18", che quindi sar di tipo non numerico e avr una lunghezza di 9 caratteri (da 10 compreso a 18 compreso risultano 9 posizioni). Anche per la variabile NATO_IL si ragiona allo stesso modo. Per la variabile SESSO indicata la specifica "$ 34". In questo caso indicata una sola colonna ad indicare che tale colonna segna l'inizio e la fine del campo. La lunghezza di tale variabile risulter cos di una sola posizione. Alle variabili REDDITO, FIGLI e TITOLO invece, come riferito sopra, verr attribuita una lunghezza di 8 posizioni indipendentemente dal numero di cifre che compongono i valori di queste variabili. Per le variabili numeriche il sistema SAS utilizza una particolare codifica (binario a virgola mobile o floating point o, come dicono alcuni, virgola fluttuante) che permette di memorizzare valori numerici composti anche da un numero di cifre maggiore di otto in sole otto posizioni di memoria. Quando il valore numerico verr trasportato dallinput buffer al PDV, il sistema SAS avr cura di eseguire la conversione opportuna. L'utilizzo di una tale codifica offre molti vantaggi per quanto riguarda la velocit di calcolo, 39

l'uniformit tra dati e la loro compattezza. Al momento della compilazione, il sistema SAS si preoccupa anche di riempire la parte descrittiva dell'archivio (o degli archivi) che saranno creati; in essa vengono registrate tutte le informazioni che possono essere utili sia al sistema SAS stesso quando dovr leggere l'archivio, sia ad un utente che vuole una documentazione dell'archivio (conoscere le variabili contenute, sapere quando e da chi stato creato, ecc.). L'unica informazione che il compilatore non in grado di riempire, il numero di osservazioni che saranno scritte nella parte dati dell'archivio.
Riserva di opportuna quantit di memoria per

INPUT BUFFER

Riserva di opportuna quantit di memoria per (VETTORE DEI DATI)

PDV

Creazione di tanti

DESCRITTORI
quanti sono gli archivi SAS da creare Traduzione del programma SAS in

LINGUAGGIO MACCHINA
Alla fase di ESECUZIONE...

Figura 2.7: Diagramma a blocchi della fase di compilazione Una volta terminata la compilazione del passo DATA, approntati cio l'input buffer, il PDV, la parte descrittiva dell'archivio di uscita e la copia di programma tradotta in linguaggio macchina, il sistema SAS passer alla seconda fase: la fase di esecuzione. Lo schema di figura 2.7 rappresenta le principali azioni del sistema SAS al momento della compilazione.

40

2.4.

Lesecuzione del passo di DATA

Nella fase di esecuzione del passo di DATA, verranno eseguite tutte le dichiarazioni che indicano una azione, ordinatamente a partire dalla prima fino all'ultima. Le dichiarazioni che non indicano un'azione contengono solo informazioni utili al compilatore per effettuare la traduzione. Lo schema di figura 2.8 mostra la logica della fase di esecuzione.
... dalla COMPILAZIONE

Inizializzazione delle variabili (PDV) con valore mancante (missing value)

INIZIALIZZAZIONE

Esecuzione delle istruzioni eseguibili nell'ordine in cui vengono incontrate

ESECUZIONE VERA E PROPRIA


ANCORA DATI FINE DATI

Copia del PDV nella parte dati del file (o dei files) SAS di uscita del passo

SCRITTURA DEL FILE SAS


FINE DATI

Al prossimo PASSO ...

Figura 2.8: Diagramma a blocchi della fase di esecuzione Prima di procedere all'esecuzione delle dichiarazioni del programma, il sistema SAS inizializza tutte le variabili del PDV a valore mancante. Quando tutte le dichiarazioni sono state eseguite, il contenuto del PDV, cos come si trova in quell'istante, viene copiato nella parte dati dell'archivio SAS, creando cos la prima osservazione. Se i dati da leggere non sono terminati, viene reinizializzato il PDV e comincia una nuova esecuzione del passo DATA a partire dalla prima dichiarazione eseguibile del 41

programma. Infine, dopo aver letto l'ultimo dato, il passo DATA termina, e verr eseguito il passo successivo, se ne esiste uno. In caso contrario terminer l'esecuzione dell'intero programma SAS.

2.5.

La dichiarazione DATA

Entrando ora nel merito delle dichiarazioni, esaminiamo listruzione DATA che, oltre ad indicare l'inizio del passo, indica i nomi degli archivi SAS che vogliamo creare. La sintassi completa di questa dichiarazione : DATA [<nome archivio 1>] [<nome archivio 2>] ...; I nomi degli archivi sono racchiusi tra parentesi quadre per indicare che sono opzionali, mentre la parola DATA una parola chiave obbligatoria. Con un passo DATA possiamo scrivere vari archivi SAS. Le regole per attribuire un nome ad un archivio sono le stesse utilizzate per formare i nomi delle variabili. Nel sistema SAS gli archivi vengono raggruppati in "librerie" che a loro volta sono contraddistinte da un nome. Anche i nomi delle librerie si formano seguendo le stesse regole. Per identificare in modo completo un archivio SAS, si pu scrivere il nome della libreria seguito da un punto e dal nome dell'archivio. Esempi di nomi completi di archivi sono: LIBRERIA.ARCHIVIO LIBMIA.ARCHIVI1 PISA.ANAGRAFE PISA.NASCITE SIENA.NASCITE Il terzo e il quarto archivio fanno parte della stessa libreria di nome PISA. Il quarto e il quinto archivio hanno lo stesso nome, ma sono due archivi distinti perch risiedono in librerie diverse. Nell'esempio di figura 2.5 noi non abbiamo indicato il nome completo dell'archivio: manca il nome della libreria. In questo caso il sistema SAS assume per convenzione, come nome di libreria, WORK. Risulta quindi equivalente scrivere: WORK. ANAGRAFE o ANAGRAFE. La libreria WORK per di tipo particolare: viene usata per registrarvi archivi di utilizzo temporaneo ed inteso che, quando termina il programma o la sessione SAS, la libreria verr distrutta con tutti i suoi archivi. Alla distruzione pensa automaticamente il sistema SAS. Questa convenzione risulta comoda almeno per due motivi: a) il disco su cui registriamo gli archivi non verr ingombrato inutilmente da dati che noi non abbiamo deciso di registrare in modo permanente (perch magari frutto di risultati intermedi o di prove); 42

b) non rischiamo di lasciare registrazioni su disco se queste non sono state volutamente rese permanenti, (ad esempio perch riservate). L'archivio creato nell'esempio di figura 2.5 risulta quindi temporaneo. Osservando ancora la sintassi della dichiarazione DATA possiamo vedere che non siamo obbligati ad indicare il nome di un archivio SAS. Potremmo quindi scrivere una dichiarazione DATA con la sola parola "DATA;". Anche in questo caso il sistema SAS assume il nome di un archivio della libreria WORK. Il nome dell'archivio sar scelto tra i nomi DATA1, DATA2, DATA3 ... . Prima di effettuare la scelta il sistema SAS controlla sul disco in uso se esistono gi archivi di nome WORK.DATA1, WORK.DATA2, WORK.DATA3, ecc. e viene assegnato il primo nome che non indica un archivio esistente. Potremmo per pensare ad un passo di DATA con cui non si vuol creare nessun archivio SAS, ma solo scrivere archivi non SAS. In questo caso, accanto alla parola DATA, dovr essere specificata la parola chiave _NULL_. La dichiarazione risulterebbe quindi: "DATA _NULL_;".

2.6.

La dichiarazione CARDS

Anche la dichiarazione CARDS non indica una azione da eseguire ma serve semplicemente al compilatore per individuare dove finiscono le dichiarazioni vere e proprie e dove invece cominciano i dati. Questa dichiarazione pu essere messa solo alla fine di un passo di DATA. Immediatamente dopo devono cominciare i dati, che sono considerati conclusi nella riga precedente quella contenente un "punto e virgola". Di seguito si riportano alcuni esempi che fanno utilizzo della dichiarazione CARDS. Nel primo i dati sono conclusi nella riga precedente la dichiarazione "RUN;", che indica normalmente la conclusione di un passo.
DATA DATIMIEI; INPUT ... ; CARDS;

... dati...
RUN; PROC PRINT DATA=DATIMIEI; ....

La dichiarazione di conclusione dei dati non deve essere 43

obbligatoriamente "RUN;. Nel prossimo esempio, infatti, essa stata omessa ma la dichiarazione PROC, che termina con un punto e virgola, sufficiente ad indicare la conclusione dei dati (e conseguentemente del passo di DATA).

DATA DATIMIEI; INPUT ... ; CARDS;

... dati...
PROC PRINT DATA=DATIMIEI; ....

Il prossimo esempio contiene un errore in quanto la riga "PROC PRINT" viene considerata erroneamente facente parte dei dati e non l'inizio di un passo di PROC.
DATA DATIMIEI; INPUT ... ; CARDS;

... dati...
PROC PRINT DATA=DATIMIEI; ....

Per evitare simili errori conviene abituarsi a concludere i dati con la dichiarazione "RUN;" o con un punto e virgola, come mostrato nell'esempio che segue.
DATA DATIMIEI; INPUT ... ; CARDS;

... dati... ;
PROC PRINT DATA=DATIMIEI; ....

Quanto visto fin qui, non ci permette di avere caratteri "punto e virgola" tra i dati. Per ovviare a questo problema, nel sistema SAS esiste anche la dichiarazione CARDS4 che, sostituita alla CARDS, specifica che i dati sono conclusi solo da una riga contenente quattro "punto e virgola" consecutivi nelle colonne 1-4.

2.7.

La dichiarazione INPUT

Nell'esempio di figura 2.5 abbiamo usato la dichiarazione INPUT per scandire i dati trascritti dopo la dichiarazione CARDS, ovviamente non organizzati in maniera SAS. La dichiarazione INPUT dovr essere sempre utilizzata tutte le volte che i dati da leggere non sono registrati con la organizzazione SAS. 44

Questa dichiarazione prevede tre tipi di sintassi per permettere la lettura di tutte le possibili organizzazioni di dati: 1. Input a colonne 2. Input a lista 3. Input a formati Nell'esempio di figura 2.5 abbiamo utilizzato la sintassi perch si adattava meglio al tipo dei dati da leggere, ma effettuare anche altre scelte senza compromettere funzionamento del nostro programma. Passiamo ora ad dettagliato delle tre sintassi. a colonne potevamo il buon un esame

2.7.1. INPUT a colonne


Abbiamo gi visto la sintassi da utilizzare con lINPUT a colonna. La scriviamo in forma generale come segue:
INPUT <nome variabile> [$] <colonna inizio > [- <colonna fine >] <nome variabile> [$] <colonna inizio > [- <colonna fine >] ... <nome variabile> [$] <colonna inizio >[- <colonna fine >];

Il "$" (dollaro) indicato tra parentesi quadra sta ad indicare che deve essere presente solo se il campo non numerico. Se i campi sono di un solo carattere (o cifra numerica) la colonna di fine pu essere omessa, come stato fatto nell'esempio di figura 2.5 per la variabile SESSO. Un campo, o parte di esso, pu essere assegnato a pi variabili. L'ordine con cui vengono elencate le variabili nella INPUT non rilevante, come si pu vedere dall'esempio che segue in cui stato letto prima il cognome e poi il nome per forzare questo ordine PDV. Il valore della variabile INIZIALE data dal primo carattere del valore del cognome. I valori dell'et e dell'altezza, che nei dati si trovano dopo il valore del sesso, vengono completamente ignorati, perch evidentemente non prevediamo di utilizzarli per i calcoli successivi.
DATA; COGNOME $ 13-20 NOME $ 1-10 INIZIALE $ 13 SESSO $ 23; /*Il seguente commento evidenzia l'incolonnamento */ /*345678901234567890123456789012345678901234567890*/ CARDS; Mario Aloia M 36 1.78 Marco Bianchi M 38 1.80 Elia Biorci M 1.75 Anna Neri F 28 1.68 Gina Rossi F 32 1.65 ; INPUT

45

Nell'esempio, inoltre, la terza osservazione ha il nome incolonnato a destra del campo indicato e la quarta ha il nome nel centro. In questo caso il sistema SAS si preoccuper di togliere gli spazi bianchi che precedono il valore e nella variabile il nome verr registrato allineato a sinistra. Il sistema SAS infatti si prende cura di allineare i valori numerici a destra (o al punto decimale se esiste) e i valori non numerici a sinistra. Ignora cio gli spazi a destra dei numeri e quelli a sinistra dei valori non numerici. Nei numeri negativi il segno dovr essere attaccato a sinistra del numero. I campi lasciati bianchi vengono considerati come valori mancanti. Il valore della variabile ETA per la terza osservazione risulter mancante. Con la INPUT a colonne possibile inoltre specificare il numero di decimali da considerare, qualora questi non siano espressi esplicitamente per mezzo di un punto decimale nel numero, come nel prossimo esempio.
DATA; INPUT NOME $ 1-10 ALTEZZA 35-38 .2 ; /*Il seguente commento evidenzia l'incolonnamento */ /*345678901234567890123456789012345678901234567890*/ CARDS; Mario Aloia M 36 1.78 Marco Bianchi M 38 1.8 Elia Biorci M 175 Anna Neri F 28 168 Gina Rossi F 32 1.65 ;

La specifica aggiuntiva fornita con la variabile ALTEZZA indica che i numeri non contenenti un punto decimale esplicito devono essere intesi come espressi con due decimali. Il valore di altezza della terza osservazione risulter cos 1.75 e quello della quarta 1.68. Nulla cambia per gli altri valori contenenti il punto. I valori relativi alla variabile ALTEZZA sono stati incolonnati indifferentemente a destra o a sinistra, ma vengono comunque letti correttamente in quanto sono sempre compresi nel campo che va da colonna 35 a colonna 38 come specificato nella dichiarazione INPUT.

2.7.2. INPUT a lista


La sintassi da utilizzare con la dichiarazione INPUT a lista risulta molto semplice. La scriviamo in forma generale come segue:
INPUT <nome variabile > [$] <nome variabile > [$] <nome variabile > [$]; ...

46

Il "$" (dollaro) indicato tra parentesi quadra sta ad indicare che deve essere presente solo se il campo non numerico. Con questo tipo di sintassi si specificano solo i nomi delle variabili ed il loro tipo. necessario specificare tutte le variabili nell'ordine in cui sono codificati i dati. Tra un valore e il successivo deve esserci almeno uno spazio che separa i due dati. Non necessario che i dati rispettino un incolonnamento prestabilito. indispensabile per indicare i valori mancanti con un punto affinch i valori da leggere rimangano sincronizzati con le variabili della dichiarazione INPUT e il sistema SAS li legga correttamente. Questa sintassi risulta essere la pi comoda quando si devono digitare i dati da un terminale, perch possono essere immessi in formato libero. Si deve tener presente che il compilatore riserva con la INPUT a lista 8 posizioni nel PDV sia per le variabili numeriche, che per quelle non numeriche. Questo significa che variabili non numeriche pi lunghe di 8 posizioni, per le quali non sia stata specificata esplicitamente la lunghezza per mezzo della dichiarazione LENGTH (descritta nel capitolo 4), vengono troncate a destra. Il prossimo esempio mostra l'utilizzo di INPUT a lista.
DATA; INPUT NOME $ COGNOME $ SESSO $ ETA ALTEZZA; CARDS; Mario Aloia M 36 1.78 Marco Bianchi M 38 1.80 Elia Biorci M . 1.75 Anna Neri F 28 1.68 Gina Rossi F 32 1.65 ;

In questo esempio stato messo un punto al posto del valore dell'et della terza osservazione in quanto tale valore sconosciuto. In questo caso il sistema SAS attribuir il valore mancante alla variabile ETA senza perdere il sincronismo. Se la INPUT a lista non trova nella riga dati letta tutte le variabili specificate, essa legge la successiva riga di dati portandola nell'input buffer e scandendola fino a trovare tutti i valori che mancano per completare la sua lettura. L'esecuzione della successiva INPUT causer la lettura della riga ancora seguente. Anche se il sistema SAS segnala l'errore su SASLOG, pu essere opportuno inibire questo comportamento per mezzo delle opzioni STOPOVER e/o MISSOVER della dichiarazione INFILE che verranno viste nel capitolo 5.

47

2.7.3. INPUT a formati


La sintassi da utilizzare con la dichiarazione INPUT la pi precisa e completa, ma anche la pi complessa. La scriviamo in forma generale come mostrato di seguito.
INPUT [<puntatore colonna>] <nome variabile > formato [lunghezza]. [<puntatore colonna>] <nome variabile > formato [lunghezza]. ... [<puntatore colonna>] <nome variabile > formato [lunghezza]. ;

Con questa sintassi oltre a specificare l'inizio del campo (puntatore colonna) e la lunghezza del campo (dopo il formato) si forniscono informazioni sulla natura del campo stesso. Cominciamo a vedere come si devono specificare i puntatori di colonna. La sintassi della INPUT a formati prevede due tipi di puntatori di colonna: assoluto e relativo. Il puntatore di colonna assoluto si indica con il simbolo @ (chiamato at in inglese) seguito da una costante numerica o una variabile numerica che identifica il numero di colonna a cui ci si deve posizionare. Ad esempio, con la specifica @15 indicheremo che il campo inizia a colonna 15. Il puntatore di colonna relativo si indica con il simbolo + seguito da una costante numerica o una variabile numerica che identifica il numero di colonne che vogliamo saltare. Ad esempio, con la specifica +5 indicheremo che il campo inizia cinque colonne dopo la fine del campo precedente, ovvero che tra il campo attuale e quello precedente ci sono cinque posizioni che non devono essere analizzate. Se non esiste un campo precedente perch il campo attuale il primo della dichiarazione INPUT, si inizia a contare da colonna 1. Qualora non si indichi nessun puntatore di colonna viene assunto il puntatore relativo +0, ovvero l'inizio del campo attuale viene assunto adiacente alla fine del campo precedente. Per quanto riguarda i formati, limitiamoci per ora ad esaminare i due pi semplici. Con dollaro seguito da un numero e da un punto indicheremo un campo non numerico di tante posizioni quante ne indica il numero che segue il dollaro. Cos "$12." indicher un campo non numerico di 12 posizioni. Analogamente con un numero seguito da un punto indicheremo un campo numerico di tante posizioni quante ne indica il numero. Cos "12." indicher un campo numerico di 12 posizioni. Con questo formato, analogamente a quanto visto per la INPUT a colonne, possibile indicare il numero di cifre decimali da considerare qualora nel campo non sia espresso esplicitamente un 48

punto. Tale numero si codifica scrivendolo accanto al punto senza lasciare spazi (ad esempio "12.1"). importante osservare che quando si specifica il nome di un formato necessario codificare sempre il punto previsto dalla sintassi (serve al sistema SAS per distinguere i nomi di variabili che non possono contenere punti, da quelli dei formati). L'esempio che segue mostra l'uso delle specifiche della INPUT a formati esaminate fino a questo punto.

DATA; INPUT NOME $10. @13 COGNOME $8. +2 SESSO $1. +2 ETA 3. @35 ALTEZZA 4.2; /*Il seguente commento evidenzia l'incolonnamento */ /*345678901234567890123456789012345678901234567890*/ CARDS; Mario Aloia M 36 1.78 Marco Bianchi M 38 1.8 Elia Biorci M 175 Anna Neri F 28 168 Gina Rossi F 32 1.65 ;

Per indicare l'inizio dei campi sono stati utilizzati indifferentemente puntatori di colonna relativi o assoluti. Il primo puntatore stato omesso in quanto, cominciando il campo a colonna 1, si pu sfruttare la regola che stabilisce che, in mancanza di specifiche, la posizione iniziale del primo campo viene assunta essere a colonna 1. In questo esempio, il valore del nome della quarta riga non risulta allineato con gli altri, ma anche in questo caso (analogamente a quanto abbiamo visto per la INPUT a colonne), il sistema SAS allinea il valore a sinistra eliminando gli spazi non significativi; questo allineamento per non viene fatto con tutti i formati (cfr. formato $CHAR). Poich il valore totalmente compreso all'interno del campo che abbiamo definito, i risultati saranno corretti come ci aspettiamo. I valori numerici relativi alla variabile ALTEZZA verranno letti dopo essere stati riallineati a destra. Anche con la INPUT a formati, i campi che risultanti vuoti, verranno letti come valore mancante (valore di ETA nella terza osservazione). Il sistema SAS mette a disposizione molti altri tipi di formati di cui ci occuperemo nei capitoli seguenti. Aggiungiamo a questo punto solo un elenco molto ridotto di formati utilizzabili per la lettura dei dati. Come vedremo in seguito, i formati disponibili sono molto numerosi, in quanto, a quelli di 49

ingresso trattati in questa sede, si devono aggiungere anche quelli di uscita come verr dettagliato nei capitoli 3 e 6. In questo elenco il valore c indica la lunghezza del campo, espressa sempre in numero di posizioni. La lettera d, che segue talvolta il punto, indica la possibilit di specificare il numero di decimali da considerare qualora nel dato non vi sia un punto decimale esplicito. c. c.d $c. $CHARc. HEXc. IBc.d PDc.d campo numerico standard (usato nell'esempio precedente). campo numerico con decimali (usato nell'esempio precedente). campo non numerico standard (usato nell'esempio precedente). campo non numerico in cui viene inibito il riallineamento automatico a sinistra. campo numerico esadecimale . campo numerico binario . campo numerico packed.

Si ribadisce che, in tutti i formati mostrati, c indica il numero di posizioni (bytes) occupate dal campo, e d il numero di decimali compresi nelle c posizioni.

2.7.4. Puntatori di colonna e di riga


Nella INPUT a formati, abbiamo gi visto come sia possibile indicare l'inizio campo o in modo assoluto, indicando con @n la colonna in cui inizia il campo, o in modo relativo alla fine del campo precedente indicando con +n il numero di colonne da trascurare (saltare). In modo analogo potremo usare i puntatori di riga. Consideriamo il seguente esempio:
DATA; INPUT NOME $10. @13 COGNOME $8.; INPUT SESSO $1. +3 ETA 3.; INPUT ALTEZZA 4.2; /*Il seguente commento evidenzia l'incolonnamento */ /*345678901234567890123456789012345678901234567890*/ CARDS; Mario Aloia M 36 1.78 Marco Bianchi M 38 1.8 PROC PRINT; RUN;

50

Nell'esempio abbiamo i dati relativi a ciascun soggetto suddivisi in tre righe (record). Per leggerli abbiamo usato tre dichiarazioni INPUT la cui azione quella di portare in successione ciascuna riga di dati nell'input buffer, dal quale in seguito verranno estratti i valori delle variabili, come mostrato nella sequenza di figura 2.9, di figura 2.10 e di figura 2.11.

DOPO LA PRIMA INPUT


| M| A| R| I| O| | | | | | | | A| L| O| I| A| | | | | | | |

INPUT BUFFER
NOME COGNOME SESSO ETA ALTEZZA

$ # # <vuoto> <vuoto> <vuoto> # Valore numerico VETTORE DEI DATI (PDV) $ Valore non numerico $ $
Mario Aloia

Figura 2.9: Contenuto di input buffer e PDV dopo la 1a INPUT La prima dichiarazione di INPUT provoca la lettura della prima riga di dati e l'estrazione dei valori delle variabili NOME e COGNOME che vengono inseriti nell'opportuna posizione del PDV. I valori delle altre variabili (alle quali stato attribuito il valore mancante a inizio ciclo) non vengono modificati in alcun modo. Non segue nessuna scrittura sull'archivio di uscita WORK.DATA1, dopo questa dichiarazione, perch esistono altre dichiarazioni da eseguire.

DOPO LA SECONDA INPUT


|M| | | |3|6| | | | | | | | | | | | | | | | | | |

INPUT BUFFER
NOME COGNOME SESSO ETA ALTEZZA

$
Mario Aloia

$
M

#
36

#
<vuoto> # Valore numerico $ Valore non numerico

VETTORE DEI DATI (PDV)

Figura 2.10: Contenuto di input buffer e PDV dopo la 2a INPUT 51

Per la seconda INPUT valgono le considerazioni fatte per la prima. Anche in questo caso non viene eseguita nessuna scrittura.

DOPO LA TERZA INPUT


|1 |. |7 |8 | | | | | | | | | | | | | | | | | | | | |

INPUT BUFFER
NOME COGNOME SESSO ETA ALTEZZA

$
Mario Aloia

$
M

$
36

#
1.78

#
# Valore numerico $ Valore non numerico

VETTORE DEI DATI (PDV)

Figura 2.11: Contenuto di input buffer e PDV dopo la 3a INPUT Con la terza INPUT viene completato il riempimento del PDV. Poich questa anche l'ultima dichiarazione del passo di DATA da eseguire, il PDV viene trascritto nell'archivio di uscita creando una nuova osservazione. In questo passo il numero di osservazioni non corrisponde al numero di righe lette. L'archivio di uscita avr, in questo caso particolare, due osservazioni a fronte di sei righe lette. Identico funzionamento si ottiene con il programma riportato di seguito nel quale abbiamo una sola dichiarazione INPUT che presenta un nuovo carattere "/" (barra).
DATA; INPUT NOME $10. @13 COGNOME $8. / SESSO $1. +3 ETA 3. / ALTEZZA 4.2; /*Il seguente commento evidenzia l'incolonnamento */ /*345678901234567890123456789012345678901234567890*/ CARDS; Mario Aloia M 36 1.78 Marco Bianchi M 38 1.8 ; PROC PRINT; RUN;

52

Tale carattere indica che la INPUT deve leggere anche i dati della successiva riga che perci dovr essere portata nell'input buffer. Questo puntatore considerato un puntatore relativo di riga. Per controllare la distribuzione dei dati nelle righe esiste anche un puntatore assoluto che si indica con il simbolo # (in inglese pound) seguito da una costante o una variabile numerica che indica da quale riga all'interno dell'input buffer deve essere letto il dato. Nell'esempio seguente si fa uso del puntatore assoluto di riga.
DATA; INPUT NOME $10. @13 COGNOME $8. #2 SESSO $1. +3 ETA 3. #3 ALTEZZA 4.2; /*Il seguente commento evidenzia l'incolonnamento */ /*345678901234567890123456789012345678901234567890*/ CARDS; Mario Aloia M 36 1.78 Marco Bianchi M 38 1.8 ; PROC PRINT; RUN;

Quando compare il puntatore assoluto seguito da costante, in compilazione, il sistema SAS prepara un input buffer composto da un numero di righe pari al numero massimo indicato dopo il simbolo #. Nel nostro caso l'input buffer sar di tre righe, come mostrato in figura 2.12. Al momento in cui viene eseguita la INPUT, le tre righe da leggere vengono portate nell'input buffer, da cui poi vengono prelevati i valori.
spazio per la prima riga

spazio per la seconda riga

spazio per la terza riga

Figura 2.12: Input buffer dell'esempio precedente

53

In questo caso non necessario prelevare i valori esattamente nell'ordine in cui vi si trovano, ma possiamo utilizzarli nel modo che ci torna meglio come si vede nell'esempio che segue.
DATA; INPUT #3 ALTEZZA 4.2 #1 NOME $10. @13 COGNOME $8. #2 SESSO $1. +3 ETA 3. ; /*Il seguente commento evidenzia l'incolonnamento */ /*345678901234567890123456789012345678901234567890*/ CARDS; Mario Aloia M 36 1.78 Marco Bianchi M 38 1.8 ; PROC PRINT; RUN;

Naturalmente l'ordine con cui le variabili vengono inserite nel PDV rispetter l'ordine di apparizione delle variabili nel programma. Se si usa dopo il simbolo "#" una variabile, a meno di specifiche particolari (opzione N= della dichiarazione INFILE che vedremo nel capitolo 5), il sistema SAS prepara un input buffer di una sola riga. Le diverse sintassi viste fin qui, possono essere utilizzate contemporaneamente in una unica dichiarazione INPUT. Pu cio essere indicato un dato nella dichiarazione seguendo la sintassi della INPUT a lista mentre per il successivo dato pu essere utilizzata la sintassi della INPUT a colonne per poi proseguire con la sintassi della INPUT a lista di nuovo o magari quella della INPUT a colonne. Ulteriori esempi ed ampliamenti della sintassi della INPUT saranno visti nel capitolo 5.

2.8.

La dichiarazione di assegnazione

La dichiarazione di assegnazione ha una sintassi simile a quella di molti altri linguaggi: variabile=espressione; Per espressione si intende una espressione aritmetica, se si hanno a disposizione valori aritmetici, o una espressione con operazioni lecite tra caratteri, altrimenti. La variabile che compare a sinistra dell'uguale sar allocata nel PDV (se non gi presente); essa assumer il valore risultante dal calcolo dell'espressione. 54

Le assegnazioni che seguono prevedono il tipo pi elementare di espressione.


X=Y; A=B; /* Ad X viene assegnato il valore di Y /* Ad A viene assegnato il valore di B */ */

Nelle assegnazioni possono essere utilizzati valori costanti:


X=3; /* Ad X viene assegnato il valore numerico 3 */ Y=-3; /* Ad Y viene assegnato il valore numerico -3 */ A='ABC'; /* Ad A viene assegnato il valore non numerico 'ABC' */

Le costanti non numeriche si racchiudono tra apici. Le costanti possono essere utilizzate in tutte le posizioni di una espressione, dove si possono utilizzare le variabili. Le espressioni aritmetiche ammettono operatori corrispondenti alle operazioni aritmetiche fondamentali: seguito da una costante o da una variabile indica il cambiamento di segno; ** indica "elevato a..."; * e / indicano la moltiplicazione e la divisione; + e indicano l'addizione e la sottrazione. Le operazioni elencate precedentemente vengono eseguite seguendo una priorit che identica a quella in uso nella convenzione dell'aritmetica (ordine corrispondente a quello di comparizione). L'esecuzione delle operazioni produce i risultati che ci aspetteremmo normalmente in aritmetica. Se si tenta di eseguire operazioni non valide, come la divisione con il divisore uguale a zero o la somma con un addendo uguale a "valore mancante", si ottiene come risultato "valore mancante". Fra le operazioni non numeriche ammesse dal sistema SAS, viene riportata di seguito solo l'operazione di concatenazione tra stringhe. L'operatore concatenazione si indica con il simbolo composto || (doppia barra verticale).
A='ABCD' || 'EFG';

equivale a:
A='ABCDEFG';

Nelle espressioni possono essere utilizzate le molte funzioni presenti nelle librerie SAS. Sono riportati di seguito alcune esempi di utilizzo.

Funzioni matematiche:

55

X=SQRT(Y); X=ABS(Y); X=SUM(Y,15,Z); X=MEAN(Y,15,Z); X=LOG(Y); X=SIN(Y);

/* assegna a X il valore della radice quadrata di Y (SQuare RooT) */ /* assegna a X il valore assoluto di Y */ /* assegna a X il valore della somma di Y, 15 e di Z */ /* assegna a X il valore della media di Y, 15 e di Z */ /* assegna a X il valore del logaritmo di Y */ /* assegna a X il valore del seno di Y */

Funzioni non matematiche:


A=SUBSTR('ABCDEFG',2,3); /* assegna ad A il valore 'BCD' perch: il primo argomento indica la stringa dalla quale si vuole estrarre una sottostringa; il secondo argomento indica il punto di partenza (secondo carattere); il terzo argomento indica la lunghezza della sottostringa (tre caratteri) */ B='ABCDEFG'; I=2; K=3; A=SUBSTR(B,I,K); /* le quattro istruzioni (che verranno eseguite di seguito) hanno lo stesso effetto di quella riportata sopra: al posto dei valori espressi come costanti compaiono variabili aventi gli stessi valori */ I=INDEX('ABCDEF','CD'); /* Viene assegnato alla variabile I il valore 3 in quanto la sottostringa 'CD' (secondo argomento) si trova nella stringa 'ABCDEF' (primo argomento) a partire dal terzo carattere */

Come possibile notare, le funzioni sono di vario tipo e accettano un numero variabile di argomenti. Gli argomenti delle funzioni sono costituiti da costanti, variabili, espressioni (variabili e costanti possono essere anche considerate un caso particolare di espressione) o, a loro volta, da funzioni. Nel seguito saranno esaminate pi in dettaglio alcune di esse. L'espressione
I=I+1;

anche se in matematica non avrebbe molto senso, nel sistema SAS sta ad indicare che alla variabile numerica I vogliamo assegnare il suo attuale valore incrementato di 1. Dopo ogni esecuzione di questa assegnazione, nella posizione del PDV corrispondente alla variabile I ci sar il valore precedente aumentato di 1; nel caso particolare che il valore di I fosse 56

mancante, dopo l'esecuzione della dichiarazione di assegnazione, I conterrebbe ancora valore mancante (poich non possibile conoscere il risultato di una addizione se uno dei due addendi sconosciuto). Consideriamo a titolo di esempio il seguente programma SAS:
DATA; INPUT ANNO INCASSO SPESE; RICAVO=INCASSO-SPESE; ANNO=ANNO+1900; CARDS; 100000000 78000000 115000000 81000000 122000000 87000000

85 86 87 ; PROC PRINT; RUN

Il PDV del programma risulter:


ANNO INCASSO SPESE RICAVO

Nel programma precedente possiamo notare che viene calcolato il valore della nuova variabile RICAVO e viene modificato il valore della vecchia variabile ANNO. La stampa prodotta dalla procedura PROC PRINT risulter:

OBS ANNO 1 2 3 1985 1986 1987

INCASSO 100000000 115000000 122000000

SPESE 78000000 81000000 87000000

RICAVO 22000000 34000000 35000000

2.9.

La dichiarazione IF-THEN-ELSE

In ogni linguaggio di programmazione ad alto livello esiste una istruzione che, in base a certe condizioni, permette l'esecuzione di una dichiarazione anzich di un'altra. Anche nel sistema SAS possibile condizionare l'esecuzione di una o pi dichiarazioni mediante l'istruzione IF-THEN-ELSE. La sintassi : IF <espressione condizionale> THEN <dichiarazione eseguibile>; ELSE <dichiarazione eseguibile>; IF, THEN e ELSE sono parole chiave che dovremo scrivere senza 57

alcuna modifica. Per espressione condizionale si intende una espressione il cui risultato vero o falso. Risulta vero che 5>3, 10<20, 5=3+2, ecc. Risultano invece false le espressioni 3=5, 2>3, 11<8, ecc. La verit dell'espressione A>10 dipende dal valore di A (contenuto nel PDV) al momento in cui viene eseguito il confronto. Per scrivere una espressione condizionale il sistema SAS mette a disposizione gli operatori di confronto da indicare con i simboli riportati in tabella di figura 2.13. simbolo
> < >= <= = = < >

simbolo
GT LT GE LE EQ NE NL NG

descrizione maggiore di (in inglese: Greater Than) minore di (in inglese: Less Than) maggiore o uguale a (in inglese: Greater or Equal) minore o uguale a (in inglese: Less or Equal) uguale a (in inglese: EQual to) diverso da (in inglese: Not Equal to) non minore (in inglese: Not Less than) non maggiore (in inglese: Not Greater than)

Figura 2.13: Operatori di confronto permessi nella dichiarazione IF I simboli riportati nella prima e nella seconda colonna sono assolutamente equivalenti; l'uso del primo o del secondo lasciato alle preferenze del programmatore. La sintassi della dichiarazione IF-THEN-ELSE specifica che se l'espressione condizionale risulta vera allora (in inglese THEN) si esegue la dichiarazione che segue la parola THEN; altrimenti (in inglese ELSE) si esegue la dichiarazione che segue la parola ELSE. Riscrivendo l'asserzione appena fatta in modo diverso, possiamo intuire meglio il significato della dichiarazione IFTHEN-ELSE: se l'espressione condizionale risulta vera allora si esegue la dichiarazione che segue la parola THEN; altrimenti si esegue la dichiarazione che segue la parola ELSE; Le dichiarazioni THEN ed ELSE sono alternative; se si esegue l'una si ignora l'altra e viceversa. Esempio:
IF A>B THEN MAGGIORE='SI'; ELSE MAGGIORE='NO';

Se vero che il valore della variabile A maggiore del valore della variabile B allora si assegna alla variabile MAGGIORE il valore 58

non numerico 'SI'; altrimenti si assegna alla variabile MAGGIORE il valore non numerico 'NO'. Vediamo ora altri esempi della dichiarazione IF-THEN-ELSE.
... IF SESSO='M' THEN MASCHI=MASCHI+1; ELSE FEMMINE=FEMMINE+1; ...

Il frammento di programma sopra riportato fa incrementare la variabile MASCHI, se vero che la variabile SESSO ha valore uguale a 'M', o la variabile FEMMINE altrimenti. Se la variabile SESSO contiene valori errati diversi da 'M' e da 'F', comunque viene incrementata la variabile FEMMINE. Solo una delle due dichiarazioni verr eseguita ad ogni esecuzione.
... IF SESSO='M' THEN MASCHI=MASCHI+1; IF SESSO='F' ELSE FEMMINE=FEMMINE+1; ...

Il frammento di programma sopra riportato fa incrementare la variabile MASCHI, se vero che la variabile SESSO ha valore uguale a 'M', o la variabile FEMMINE, se vero che la variabile SESSO ha valore uguale a 'F'. Contrariamente all'esempio precedente, se la variabile SESSO contiene valori errati diversi da 'M' e da 'F' non viene incrementata nessuna variabile.
... IF ANNO < 100 THEN ANNO=ANNO+1900; ...

Nell'ultimo esempio non stata indicata nessuna azione alternativa con la dichiarazione ELSE. Essa pu mancare quando non abbiamo da definire una azione da eseguire in caso di espressione condizionale falsa; non pu mai mancare invece la THEN. Se essa venisse omessa, la dichiarazione IF-THEN-ELSE si trasformerebbe in una IF subsetting, che verr esaminata nel paragrafo 2.17. Le dichiarazioni che possono essere condizionate sono tutte quelle che indicano un'azione da compiere in fase di esecuzione; potranno essere condizionate dichiarazioni di INPUT, assegnazioni e le stesse dichiarazioni di IF-THEN-ELSE; non possono essere invece condizionate quelle che danno solo indicazioni al 59

compilatore come DATA o CARDS, n tanto meno passi di PROC, come mostrato nell'esempio seguente.
... IF ..condizione.. THEN PROC PRINT; /*esempio di IF*/ ELSE PROC MEANS;/* e r r a t a */ ...

Segue un esempio di dichiarazione IF-THEN-ELSE che ne condiziona un'altra:


... IF A=3 THEN INPUT X Y; ELSE IF A>10 THEN X=10; ELSE X=A; ...

In questo caso se la prima condizione (A=3) vera si esegue la dichiarazione INPUT ignorando completamente la dichiarazione IF che segue. Se invece la prima condizione falsa (non vero che A=3) si esegue la seconda IF; quindi se risulta vero che A>10 si esegue la prima assegnazione (X=10) ignorando la seconda altrimenti si esegue la seconda (X=A) ignorando la prima. Le espressioni condizionali possono essere composte da pi confronti combinati tra loro dagli operatori logici indicati nella tabella di figura 2.14. simbolo
| &

simbolo descrizione OR oppure AND e NOT non

Figura 2.14: Operatori logici permessi nella dichiarazione IF Anche con questi simboli abbiamo libert di scelta tra la prima colonna e la seconda. Il primo operatore ( | o OR) indica che affinch risulti vera l'espressione totale occorre che almeno un confronto sia vero. Esempio:
... IF A>B | C=10 THEN ...; ELSE ...; ...

60

Verr eseguita la dichiarazione che segue la parola chiave THEN se tutta l'espressione condizionale risulta vera, ovvero se almeno uno dei due confronti risulta vero. Se sono veri entrambi soddisfatta la condizione che almeno uno risulti vero, perci tutta l'espressione risulter vera. Con il secondo operatore (& o AND) invece, affinch tutta l'espressione risulti vera occorre che tutti i confronti risultino veri. Esempio:
... IF A>B & C=10 THEN ...; ELSE ...; ...

Lo stesso risultato si ottiene scrivendo gli operatori di confronto per esteso.


... IF A GT B AND C EQ 10 THEN ...; ELSE ...; ...

Con l'operatore (NOT) si pu negare una condizione; questo operatore esprime il concetto che una espressione risulta vera se non si verifica una certa condizione:
... IF (A>B) THEN ...; ELSE ...; ...

In quest'ultimo caso si eseguir la dichiarazione seguente la parola THEN se non si verifica che A>B. Combinando variamente i vari operatori e con l'uso di parentesi si pu arrivare ad avere espressioni condizionali molto complesse, ma preferibile inizialmente, quando possibile, non addentrarci troppo in espressioni complicate e difficili da rileggere come quella che segue:
... IF (((A>B AND C=10) OR X=Y) & STR ='ABC') OR Z=3 THEN ...; ELSE ...; ...

Nell'esempio sopra riportato prima vengono calcolati i due confronti nella parentesi pi interna, che, se ambedue veri, daranno luogo ad un valore "vero"; "falso" altrimenti. Il valore cos ottenuto verr esaminato insieme al risultato del confronto X=Y; e cos di seguito. 61

La dichiarazione IF accetta anche un valore numerico (costante, contenuto di variabile o risultato di espressione numerica) al posto dell'espressione condizionale. In tal caso il valore 0 (zero) ed il valore mancante sono considerati "FALSO"; tutti gli altri valori sono considerati "VERO".

2.10.

La dichiarazione DO-END

La dichiarazione IF-THEN-ELSE prevede il condizionamento di una sola dichiarazione. Cos, quando dobbiamo condizionarne molte, possiamo ripetere pi volte la IF-THEN-ELSE con la medesima condizione. In questi casi per il sistema SAS prevede che pi istruzioni vengano raggruppate e considerate come un unico inscindibile blocco. Per indicare l'inizio del blocco useremo la parola "DO;" e per indicarne la fine useremo "END;". La sintassi di una dichiarazione IF-THEN-ELSE con utilizzo di DO-END diviene cos:
IF <espressione condizionale> THEN DO; <dichiarazione eseguibile>; <dichiarazione eseguibile>; ... END; ELSE DO; <dichiarazione eseguibile>; <dichiarazione eseguibile>; ... END;

In questo caso se la condizione specificata risulta vera, vengono eseguite tutte le dichiarazioni che si trovano tra le parole "THEN DO;" e la parola "END;" successiva. Se, al contrario, la condizione specificata risulta falsa, vengono eseguite tutte le dichiarazioni che si trovano tra le parole "ELSE DO;" e la parola "END;" successiva. Bench il sistema SAS non obblighi a rispettare nessun incolonnamento, come abbiamo gi accennato utile rispettare un certo allineamento quando scriviamo i programmi. Questo consiglio si rivela particolarmente utile quando si utilizzano dichiarazioni IF-THEN-ELSE. Esse infatti possono divenire difficili da leggere e quindi da controllare e eventualmente correggere. Non sempre infatti riusciamo a prima vista a riconoscere un costrutto sintattico come quello mostrato nel seguente esempio.
... IF (((A>B AND C=10) OR X=Y) & STR='ABC') OR Z=3 THEN A=3; ELSE IF (((A>B AND C=10) OR X=Y) & STR='ABC') THEN B=87; ELSE IF (((A>B AND C=10) OR X=Y) & STR='ABC') THEN A=4; ELSE B=52; ...

62

Riscrivendo il frammento di programma precedente e rispettando un opportuno incolonnamento, otteniamo la seguente scrittura che, bench identica a quella precedente nella sostanza, risulta essere molto pi leggibile e facile da capire e controllare.
..... IF (((A>B AND C=10) OR X=Y) & STR='ABC') OR Z=3 THEN A=3; ELSE IF (((A>B AND C=10) OR X=Y) & STR='ABC') THEN B=87; ELSE IF (((A>B AND C=10) OR X=Y) & STR='ABC') THEN A=4; ELSE B=52; .....

Una abitudine abbastanza diffusa quella di incolonnare le parole chiave IF e ELSE pi a sinistra del resto del testo, come si vede dal seguente esempio:
..... IF (((A>B AND C=10) OR X=Y) & STR='ABC') OR Z=3 THEN A=3; ELSE IF (((A>B AND C=10) OR X=Y) & STR='ABC') THEN B=87; ELSE IF (((A>B AND C=10) OR X=Y) & STR='ABC') THEN A=4; ELSE B=52; .....

Anche con questo tipo di incolonnamento si mette in risalto l'appartenenza di un parola chiave a una dichiarazione IF. Il consiglio che ne consegue di scegliere il tipo di incolonnamento pi consono, ma poi seguire sempre quello scrupolosamente. inoltre consigliabile di utilizzare nelle espressioni aritmetiche o condizionali, coppie di parentesi, anche se inutili, quando queste riescono a chiarire meglio il significato della espressione. Cos ad esempio l'espressione:
A=B*C+D*E;

risulta pi chiara se la scriviamo:


A=(B*C)+(D*E);

La stessa considerazione vale per le coppie di "DO;-END;", che possono essere aggiunte in un programma, se lo rendono pi leggibile. Esempio:
IF A>B THEN DO; IF C>D THEN X=1; ELSE X=0;

ELSE

END; DO; IF C=8 THEN X=3; ELSE X=4; END;

Le coppie "DO;-END;" sono del tutto inutili nel contesto della 63

dichiarazione, ma favoriscono la comprensione del costrutto.

2.11. La dichiarazione RETAIN e la totalizzazione


Con le dichiarazioni presentate precedentemente gi possibile scrivere un programma che esegua elaborazioni di dati di una certa complessit. Si pu rilevare per che con le dichiarazioni fin qui viste, non possibile mantenere per pi di un ciclo i risultati delle elaborazioni, poich ad ogni ciclo il sistema SAS si preoccupa di inizializzare il PDV cancellando ogni valore ricavato in cicli precedenti. Ci serve perci una dichiarazione che istruisca il compilatore a marcare "intoccabili" alcune variabili del PDV, i cui dati devono essere mantenuti integri quando comincia un nuovo ciclo di esecuzione. La dichiarazione che il sistema SAS ci mette a disposizione la RETAIN. Tale dichiarazione permette di elencare le variabili che non devono essere inizializzate a valore mancante all'inizio di ogni ciclo del passo di DATA e consente di specificare per esse un valore iniziale che dovr essere presente nel PDV quando il passo di DATA viene eseguito per la prima volta. La sintassi : RETAIN <lista di variabili> <valore iniziale> <lista di variabili> <valore iniziale> ................. ; Un possibile utilizzo della RETAIN viene mostrato nel programma di figura 2.15, il quale legge e totalizza i risultati elettorali relativi ad un candidato, che man mano stanno pervenendo dai vari seggi .
DATA; RETAIN TOT_VOTI N_SEGGI 0; INPUT SEGGIO $ VOTI; N_SEGGI=N_SEGGI+1; TOT_VOTI=TOT_VOTI+VOTI; CARDS; A 3 B 5 C 2 D 8 E 10 PROC PRINT; RUN;

Figura 2.15: Esempio di uso della dichiarazione RETAIN

64

Il PDV del passo di DATA risulta cos composto:


TOT_VOTI N_SEGGI SEGGIO VOTI

La stampa fornitaci dalla PROC PRINT risulta:


OBS TOT_VOTI N_SEGGI SEGGIO VOTI 1 2 3 4 5 3 8 10 18 28 1 2 3 4 5 A B C D E 3 5 2 8 10

Infatti inizialmente il PDV, preparato dal compilatore, contiene valore vuoto per le variabili non specificate nella dichiarazione RETAIN e 0 per le variabili specificate. Si noti che per la variabile non numerica SEGGIO il valore vuoto equivale alla stringa nulla ed rappresentato da una serie di spazi, mentre per la variabile numerica VOTI rappresentato da un punto.
TOT_VOTI 0 N_SEGGI 0 SEGGIO . VOTI

La sequenza dei contenuti del PDV alla fine di ogni ciclo :


TOT_VOTI 3 8 10 18 28 N_SEGGI 1 2 3 4 5 SEGGIO A B C D E VOTI 3 5 2 8 10

Consideriamo il caso in cui in valore del seggio C non arrivi in tempo utile per una prima esecuzione del programma. I dati a disposizione sarebbero quindi mancanti per la variabile VOTI nella terza osservazione. Il terzo dato dell'esempio di figura 2.15 si trasforma pertanto da:
C 2

a:
C .

Il punto indica che il valore della variabile VOTI mancante. In questo caso il sistema SAS, nella fase di esecuzione, si trova a dover sommare un valore conosciuto ad un valore mancante (sconosciuto) relativo alla variabile VOTI. Il risultato che ne deriva 65

valore mancante. La variabile TOT_VOTI della terza osservazione contiene cos valore mancante. Nel successivo ciclo il problema si ripete perch anche questa volta uno degli operandi dell'addizione (la variabile TOT_VOTI) non conosciuto. La sequenza dei PDV, alla fine di ogni ciclo, quella rappresentata di seguito.
TOT_VOTI 3 8 . . . N_SEGGI 1 2 3 4 5 SEGGIO A B C D E VOTI 3 5 . 8 10

Se noi vogliamo conoscere almeno i risultati parziali dei dati pervenuti, dobbiamo modificare il programma. Un sistema molto semplice, mostrato nel programma seguente, quello di introdurre una dichiarazione IF-THEN-ELSE che eviti di eseguire l'addizione quando il valore di VOTI sconosciuto, in modo da mantenere nella variabile TOT_VOTI il valore che aveva al termine del ciclo precedente.
DATA; RETAIN TOT_VOTI N_SEGGI 0; INPUT SEGGIO $ VOTI; N_SEGGI=N_SEGGI+1; IF VOTI= . THEN TOT_VOTI=TOT_VOTI+VOTI; CARDS; A 3 B 5 C . D 8 E 10 PROC PRINT; RUN;

Un modo pi elegante per risolvere il problema, mostrato in figura 2.16, consiste nell'usare la funzione SUM. La sintassi di questa funzione, la seguente: variabile = SUM (<argomento 1>, ..... , <argomento n > ); Questa funzione ritorna in variabile la somma di tutti i valori che compaiono come argomenti (costanti, variabili numeriche, espressioni). Nel caso che uno o pi argomenti assumano valore mancante, questi non vengono considerati nella somma.

66

DATA; RETAIN TOT_VOTI N_SEGGI 0; INPUT SEGGIO $ VOTI; N_SEGGI=N_SEGGI+1; TOT_VOTI=SUM(TOT_VOTI,VOTI); CARDS; A 3 B 5 C . D 8 E 10 PROC PRINT; RUN;

Figura 2.16: Esempio di totalizzazione con la funzione SUM La stampa della PROC PRINT dei due programmi precedenti risulta identica:
OBS TOT_VOTI N_SEGGI SEGGIO VOTI 1 2 3 4 5 3 8 8 16 26 1 2 3 4 5 A B C D E 3 5 . 8 10

2.12.

La dichiarazione SUM

Il sistema SAS mette a disposizione una dichiarazione specifica per facilitare la totalizzazione. Si tratta della dichiarazione SUM (da non confondersi con la funzione omonima) anche se questa parola non compare nella dichiarazione stessa. Infatti la sua sintassi : variabile+espressione; dove: Espressione viene calcolata e il valore risultante sommato a variabile; questa somma non viene effettuata se il risultato di espressione valore mancante. In tal caso il valore di variabile rimane invariato. Inoltre, quando il compilatore SAS incontra questa dichiarazione, inserisce automaticamente una "RETAIN variabile" con valore iniziale zero. quindi superfluo codificare esplicitamente la RETAIN per quella variabile, se il valore iniziale deve essere 0. Il programma di figura 2.17, che presenta due dichiarazioni, del tutto equivalente a quello di figura 2.16 e produce la stessa uscita (cambia solo l'ordine con cui sono stampate le variabili). 67

DATA; INPUT SEGGIO $ VOTI; N_SEGGI+1; TOT_VOTI+VOTI; CARDS; A 3 B 5 C . D 8 E 10 PROC PRINT; RUN;

Figura 2.17: Esempio di uso della dichiarazione SUM

2.13.

La dichiarazione SET

Tutti gli esempi presi in considerazione fino a questo punto leggono un archivio di tipo tradizionale e dopo le necessarie elaborazioni scrivono un archivio organizzato alla maniera SAS. L'esigenza di convertire archivi tradizionali in archivi SAS molto diffusa, specialmente nei casi in cui il sistema SAS stato introdotto da poco tempo. In questo caso tutti gli archivi a disposizione sono di tipo tradizionale e la prima cosa da fare la creazione di archivi SAS partendo da quelli esistenti. Una volta che gli archivi SAS sono a disposizione, se abbiamo avuto l'accortezza di registrarli in modo permanente sui nostri supporti magnetici, possiamo sfruttarli godendo cos dei numerosi vantaggi che essi offrono. Come primo vantaggio possiamo citare il fatto che normalmente gli archivi SAS di certe dimensioni occupano minore spazio, anche se pu sembrare che il registrare la parte descrittiva possa causare un aumento di volume. Gli archivi SAS infatti occupano solo la parte necessaria per registrare dati e descrittori e non hanno mai spazi di riserva in previsione di possibili aggiunte di nuovi campi come invece si usa per i record degli archivi tradizionali (i cosiddetti FILLER). Inoltre le registrazioni vengono sempre ottimizzate tenendo conto del tipo di supporto sul quale sono memorizzati i dati (caratteristiche fisiche del modello di disco, ecc.). Se l'archivio non piccolissimo lo spazio occupato dalla parte descrittiva risulta trascurabile rispetto a quello risparmiato dalla ottimizzazione e dalla assenza di FILLER. Altro vantaggio importante consiste nel fatto che gli archivi SAS sono molto pi facili da usare (non dobbiamo progettare o utilizzare macchinosi tracciati record per individuare i dati, in quanto i nomi delle variabili e la loro collocazione sono gi conosciuti dal sistema) e abbiamo a disposizione una serie di 68

programmi di utilit che facilmente ci permettono di consultarli, aggiornarli, stamparli, unirli, ecc. Tutte le PROC infatti sono in grado di utilizzare gli archivi SAS e molte di esse si possono utilizzare anche in modo interattivo. Molti altri vantaggi incoraggiano l'uso di archivi SAS; infatti essi sono automaticamente documentati, anche se nessuno li ha espressamente descritti, inoltre essi possono essere utilizzati anche da utenti finali che non conoscono la programmazione, ma sanno solo usare qualche semplice procedura SAS. Ma il vantaggio che pi gradito ad ogni programmatore quello di poter aggiungere variabili ad un archivio senza dover obbligatoriamente modificare tutti i programmi che lo usano. La dichiarazione che ci permette di leggere gli archivi organizzati alla maniera SAS, e che dovremo utilizzare per la lettura in sostituzione della dichiarazione INPUT, la SET. La sintassi molto semplice: SET [<nome di archivio SAS>]; Se il nome dell'archivio viene omesso, o viene utilizzata la parola chiave _LAST_, si intende che si vuol leggere l'ultimo archivio SAS creato nella sessione o programma in corso. Per comprendere come si utilizza la dichiarazione SET consideriamo l'esempio di figura 2.18 con il quale si crea un archivio SAS di tipo permanente (ha il nome a due livelli).
DATA PERM.ANAGRAFE; INPUT NOME $ 1-8 COGNOME $ 10-18 NATO_IL $ 21-30 SESSO $ 34 REDDITO 37-45 FIGLI 49-50 TITOLO 53-54; CARDS; Mario Aloia 16/10/1952 M 32000000 1 1 Marco Bianchi 15/08/1975 M 26000000 0 2 Elia Biorci 15/08/1950 M 27000000 1 1 Anna Neri 22/11/1960 F 80000000 5 0 Gina Rossi 11/05/1956 F 25000000 2 2 Licia Saba 15/08/1965 F 6500000 2 3 Enzo Verdi 12/08/1962 M 35000000 1 1 Guido Zini 5/08/1946 M 15000000 1 1 RUN;

Figura 2.18: Creazione dell'archivio SAS permanente PERM.ANAGRAFE Immaginiamo ora di voler aggiungere alla variabile REDDITO il valore degli assegni familiari ipotizzando che per ogni figlio vengano concesse 850000 lire annue. Scriveremo allora il seguente programma SAS:
DATA NUOVA.ANAGRAFE; SET PERM.ANAGRAFE; REDDITO=REDDITO+850000*FIGLI; PROC PRINT; RUN;

69

Questo programma legge i dati dall'archivio SAS di nome PERM.ANAGRAFE e crea un nuovo archivio SAS di nome NUOVA.ANAGRAFE. Entriamo nel dettaglio delle fasi di compilazione e di esecuzione. In compilazione il sistema SAS deve riservare spazio nel PDV per ogni variabile presente nel programma. Deve poi costruire la parte descrittiva del nuovo file da creare. Le variabili che fanno parte del PDV, anche se non compaiono esplicitamente per nome, sono quelle dell'archivio PERM.ANAGRAFE pi eventuali altre, scritte in modo esplicito nel passo di DATA. Il PDV risulter perci:
NOME COGNOME NATO_IL SESSO REDDITO FIGLI TITOLO

anche se le variabili che compaiono in modo esplicito sono solo REDDITO e FIGLI. Con la dichiarazione SET il sistema SAS non fa uso di input buffer, come stato inteso in questo testo, in quanto non sono necessarie ricerche di dati, n conversioni di numeri per i dati che si leggono. Nel sistema SAS possibile anche rimpiazzare un archivio SAS dopo aver apportato qualche modifica ai valori delle sue variabili o al numero delle variabili o delle osservazioni. Si consiglia cautela nell'usare lo stesso archivio in ingresso ed in uscita, in quanto al termine del passo di DATA, l'archivio originale sar comunque sostituito. Nel seguente esempio l'archivio PERM.ANAGRAFE viene rimpiazzato da un archivio che ha lo stesso numero di variabili e di osservazioni.
DATA PERM.ANAGRAFE; SET PERM.ANAGRAFE; REDDITO=REDDITO+850000*FIGLI; RUN;

Nel prossimo esempio, invece, l'archivio PERM.ANAGRAFE viene rimpiazzato da un archivio che ha lo stesso numero di osservazioni ed una variabile in pi. La variabile ASSEGNI verr aggiunta come ultima variabile sia nel PDV, sia nell'archivio creato.
DATA PERM.ANAGRAFE; SET PERM.ANAGRAFE; ASSEGNI=850000*FIGLI; RUN;

70

2.14.

Le dichiarazioni DROP e KEEP

Abbiamo esaminato fino a questo punto alcune delle molte possibilit offerte dal passo DATA. Non abbiamo per ancora preso in considerazione come fare per passare da un archivio SAS completo ad un altro pi "piccolo" dimensionato per una particolare elaborazione che si intende effettuare. Con il termine "piccolo", si pu intendere sia un archivio con un numero minore di variabili (ovvero pi "stretto" dell'originale), sia un archivio con un minor numero di osservazioni (ovvero pi "corto" dell'originale). Consideriamo in questo paragrafo due dichiarazioni che ci permettono di specificare esattamente quali variabili scrivere negli archivi SAS creati in un passo DATA. Esse permettono anche di eliminare variabili di comodo o temporanee, create nel corso del passo di DATA, che non si vogliono riportare negli archivi di uscita. Le due dichiarazioni, complementari fra di loro, sono DROP e KEEP ed hanno la seguente sintassi: DROP <lista di variabili>; KEEP <lista di variabili>; In un passo di DATA consigliabile specificare solo una delle due. La dichiarazione DROP indica le variabili del PDV che non vogliamo scrivere nell'archivio di uscita. Con la dichiarazione KEEP invece indichiamo le variabili del PDV che dovranno essere presenti nell'archivio di uscita. Quando si usa la KEEP nell'archivio di uscita saranno trascritte le variabili e solo le variabili elencate nella dichiarazione. Consideriamo i seguenti esempi che fanno uso dell'archivio creato dal programma di figura 2.18.
DATA PERM.ANAGRAFE; SET PERM.ANAGRAFE; REDDITO=REDDITO+850000*FIGLI; DROP NATO_IL FIGLI TITOLO; PROC PRINT; RUN;

Con la dichiarazione DROP abbiamo specificato quali sono le variabili che non vogliamo portare nell'archivio di uscita (le tre variabili NATO_IL FIGLI e TITOLO), anche se tali variabili sono presenti nel PDV e possono essere utilizzate per eventuali calcoli. Invece della dichiarazione DROP, con la specifica delle variabili da scartare, possiamo utilizzare alternativamente la dichiarazione KEEP, con la specifica delle variabili da mantenere, ottenendo esattamente lo stesso risultato. La scelta tra le due dichiarazioni solo una questione di risparmio di scrittura. Se, ad esempio, avessimo 50 variabili e ne dovessimo eliminare solo due useremmo la DROP specificando le due 71

variabili da scartare e non la KEEP seguita dai nomi di 48 variabili da mantenere! Viceversa se tra 50 variabili ne dovessimo mantenere solo due converrebbe usare la KEEP. Il programma che segue assolutamente equivalente a quello precedente pur utilizzando la dichiarazione KEEP al posto della DROP.
DATA PERM.ANAGRAFE; SET PERM.ANAGRAFE; REDDITO=REDDITO+850000*FIGLI; KEEP NOME COGNOME SESSO REDDITO; PROC PRINT; RUN;

Negli esempi abbiamo scritto le dichiarazioni DROP e KEEP alla fine del programma, ma esse potevano essere codificate in qualsiasi punto del programma senza cambiare l'effetto ottenuto. Queste dichiarazioni infatti servono solo nella fase di compilazione per indicare al compilatore quali variabili scrivere nel descrittore dell'archivio di uscita. Inoltre, non indicando una azione per la fase di esecuzione, non possibile usarle come dichiarazioni condizionate da una IF. Entrambi i programmi che precedono creeranno durante la fase di compilazione, il seguente PDV:
NOME COGNOME NATO_IL SESSO REDDITO FIGLI TITOLO

In entrambi gli esempi, la stampa effettuata dal passo di PROC PRINT sar la seguente:
OBS 1 2 3 4 5 6 7 8 NOME Mario Marco Elia Anna Gina Licia Enzo Guido COGNOME SESSO REDDITO Aloia Bianchi Biorci Neri Rossi Saba Verdi Zini M M M F F F M M 32850000 26000000 27850000 84250000 26700000 8200000 35850000 15850000

2.15.

La dichiarazione RENAME

A volte pu essere utile cambiare il nome ad una o pi variabili di un archivio SAS. Per fare ci, il sistema SAS mette a disposizione due metodi: il primo fa uso della PROC DATASETS che, in modo interattivo e senza dover ricreare l'archivio che si intende 72

modificare, permette di cambiare i nomi delle variabili desiderate. Il secondo metodo, che vediamo in questo paragrafo, fa uso della dichiarazione RENAME. Si tratta di una dichiarazione che serve solo a dare informazioni al compilatore e che non ha nessun effetto al momento della esecuzione. Pu quindi essere posta in qualsiasi punto del programma senza variare il suo significato. Non pu essere una dichiarazione condizionata da una IF. La forma sintattica :

RENAME <vecchio nome>=<nuovo nome> <vecchio nome>=<nuovo nome> ...; Prima di vedere alcuni esempi della RENAME, creiamo un archivio SAS permanente di nome PERM.ABC contenente 2 osservazioni e 3 variabili (A, B e C).
DATA PERM.ABC; INPUT A B C; CARDS; 1 2 3 4 5 6 ;

Figura 2.19: Creazione dell'archivio SAS permanente PERM.ABC L'esempio che segue mostra come una variabile che ha un nome nel PDV viene trasferita nell'archivio di uscita con un nome diverso.
DATA USCITA; SET PERM.ABC; RENAME A=X B=Y C=Z; PROC PRINT; RUN;

Il PDV di questo passo di DATA contiene le variabili A, B e C, ma l'archivio USCITA conterr le variabili X, Y e Z. La stampa prodotta dal passo di PROC PRINT sar la seguente:
OBS 1 2 X 1 4 Y 2 5 Z 3 6

Il fatto che le variabili assumano nell'archivio di uscita i nuovi nomi indicati nella dichiarazione RENAME non deve far pensare che nel programma si possano utilizzare i nomi variati. Nel PDV esse mantengono il loro nome originale e questo nome deve essere 73

utilizzato in eventuali altre istruzioni come mostrato nell'esempio che segue. Esso si compone di tre passi: 1. il primo passo di DATA, legge l'archivio PERM.ABC creato in figura 2.19 e crea un archivio SAS di nome USCITA. Per effetto della dichiarazione RENAME le tre variabili A, B e C vengono registrate nell'archivio USCITA con i nomi X, Y e Z. Poich nel PDV di questo passo compaiono i vecchi nomi delle variabili, anche le dichiarazioni di assegnazione devono usare i vecchi nomi. 2. nel secondo passo di DATA le variabili X, Y e Z vengono lette dall'archivio USCITA. Anche in questo caso i vecchi nomi sono quelli che, comparendo nel PDV, possono essere utilizzati nelle dichiarazioni di assegnazione. Per effetto delle nuova RENAME i nomi verranno ulteriormente cambiati nel file di uscita USCITA2 in ALFA, BETA e GAMMA rispettivamente.
DATA USCITA; SET PERM.ABC; A=A+1; C=C-1; RENAME A=X B=Y C=Z; DATA USCITA2; SET USCITA; X=X+1; Z=Z-1; RENAME X=ALFA Y=BETA Z=GAMMA; PROC PRINT DATA=USCITA2; RUN;

3. Infine il terzo passo produrr la stampa dell'archivio USCITA2 che ha gli ultimi nomi delle variabili. Il risultato finale del programma sar:
OBS 1 2 ALFA BETA GAMMA 3 6 2 5 1 4

74

2.16. DROP, KEEP e RENAME date come opzioni


Le dichiarazioni DROP, KEEP e RENAME viste nei due paragrafi precedenti, possono essere usate in un passo di DATA anche come opzioni della dichiarazione DATA, al momento in cui si definiscono gli archivi SAS di uscita:
DATA ArchivioSAS DATA ArchivioSAS DATA ArchivioSAS (DROP= variabile-1 variabile-2 ...); (KEEP= variabile-1 variabile-2 ....); (RENAME=(vecchio-nome-1=nuovo-nome-1..));

Esse possono essere usate anche come opzioni della dichiarazione SET (o MERGE o UPDATE che vedremo nel capitolo 5), al momento in cui si definiscono gli archivi SAS di ingresso:
SET ArchivioSAS SET ArchivioSAS SET ArchivioSAS (DROP= variabile-1 variabile-2 ...); (KEEP= variabile-1 variabile-2 ....); (RENAME=(vecchio-nome-1=nuovo-nome-1..));

In entrambi i casi la sintassi da usare leggermente diversa da quella che abbiamo visto nei paragrafi precedenti in quanto si deve introdurre il carattere "=" (uguale). Nel primo caso, in cui la DROP, KEEP e RENAME sono utilizzate come opzioni dell'archivio di uscita, vale tutto quanto stato detto nei paragrafi precedenti. Quando DROP, KEEP o RENAME vengono invece utilizzate come opzioni di un archivio di ingresso, indichiamo al compilatore che le operazioni devono essere effettuate al momento della lettura dell'archivio, prima cio di creare le variabili nel PDV. Questo significa che troviamo un riflesso immediato delle opzioni specificate direttamente nel PDV. Come esempio creiamo un archivio SAS di nome USCITA che useremo in seguito.
DATA USCITA; INPUT A B C; CARDS; 1 2 3 4 5 6 RUN;

Il PDV del file USCITA contiene evidentemente tre variabili: A, B e C. Il seguente passo di DATA usa una opzione DROP come caratteristica dell'archivio di uscita. 75

DATA

USCITA2 (DROP=A C); SET USCITA; B=A+1; /* genera B=2 e B=5 nei due cicli RUN;

*/

Il PDV costituito dalle variabili A, B e C lette nell'archivio USCITA, che quindi possono essere utilizzate nel corso del passo di DATA; cos la dichiarazione "B=A+1" sommer 1 al valore della variabile A letta con la dichiarazione SET. L'archivio USCITA2 contiene solamente la variabile B, in quanto A e C sono state ignorate per effetto della DROP. Il seguente passo di DATA identico al precedente, ma la opzione DROP utilizzata come caratteristica dell'archivio di ingresso.
DATA USCITA2; SET USCITA (DROP=A C); B=A+1; /* genera sempre B=valore mancante */ RUN;

Il PDV, e quindi l'archivio USCITA2, costituito dalla variabile A, definita nel corso del passo di DATA e dalla variabile B letta nell'archivio USCITA (le altre due variabili A e C dell'archivio USCITA sono ignorate per effetto della DROP). In questo caso la dichiarazione "B=A+1" genera valore mancante, in quanto viene sommato 1 non al valore della variabile A letta con la dichiarazione SET, ma ad una variabile definita nel corso del programma a cui non mai stato assegnato alcun valore. Per capire perch nel sistema SAS stata introdotto l'uso della DROP e KEEP come caratteristica degli archivi di uscita, consideriamo il seguente esempio:
DATA USCITA1 (DROP=C) USCITA2 (DROP=A B); SET USCITA; PROC PRINT DATA=USCITA1; PROC PRINT DATA=USCITA2; RUN;

In questo esempio si prevede di creare in un unico passo due archivi SAS. Nella dichiarazione DATA infatti sono presenti due nomi di archivi SAS (nomi di archivi temporanei in quanto sono ad un solo livello). I due archivi, USCITA1 e USCITA2, vengono scritti contemporaneamente alla fine del passo e con i dati dello stesso PDV. Il PDV risulta composto da tutte le variabili che compaiono nell'archivio USCITA (cio A, B e C), ma negli archivi di uscita 76

non vengono copiate tutte le variabili. Infatti a causa delle due diverse opzioni DROP specificate come opzioni degli archivi di uscita, nell'archivio USCITA1 verranno registrate le variabili A e B, mentre nell'archivio USCITA2 verr registrata solo la variabile C. La stampa dell'archivio USCITA1 risulter:
OBS 1 2 A 1 4 B 2 5

mentre la stampa dell'archivio USCITA2 risulter:


OBS 1 2 C 3 6

Anche nei passi di PROC, come si vede nell'esempio seguente, si possono usare le opzioni DROP e KEEP per limitare il numero di variabili da elaborare. Ad esempio il seguente passo di PROC:
PROC PRINT DATA=USCITA (DROP=A C); RUN;

produce la seguente uscita:


OBS 1 2 B 2 5

2.17. Le dichiarazioni IF Subsetting e DELETE


Abbiamo visto nei paragrafi precedenti come sia possibile, con le dichiarazioni DROP e KEEP, scegliere le variabili che debbono essere lette da un archivio SAS o che devono essere riportate in un archivio SAS creato in un passo DATA. Spesso per abbiamo anche l'esigenza di scegliere le osservazioni da scrivere nell'archivio di uscita. Consideriamo i dati anagrafici riportati in tabella di figura 2.1. Immaginiamo di voler proporre alle persone a cui si riferiscono i dati della tabella di figura 2.1, l'acquisto di prodotti per bambini. Tra tutte le osservazioni presenti dovremo scegliere solo quelle in cui il valore della variabile FIGLI non zero. Ci serve una dichiarazione che ci permetta tale scelta. 77

Il sistema SAS mette a disposizione due dichiarazioni che possiamo utilizzare indifferentemente in questi casi. Iniziamo a esaminare la dichiarazione DELETE. La sintassi di questa dichiarazione : DELETE; Ogni volta che in fase di esecuzione il sistema SAS incontra una DELETE, torna alla prima dichiarazione eseguibile del passo di DATA dopo aver inizializzato il PDV, assegnando valori mancanti a tutte le variabili. In questo caso la scrittura del PDV nell'archivio di uscita non viene eseguita. Si perde cos ogni traccia della osservazione che era in elaborazione in quel momento. Questo funzionamento risulta molto utile quando da un archivio devono essere scelte osservazioni in base a un qualche criterio. Potremmo ad esempio essere interessati solo ad osservazioni esenti da errori, o a quelle riportanti dati relativi ad un certo periodo, ecc.. Il programma che segue sceglie tra tutte le osservazioni solo quelle in cui la variabile FIGLI diversa da zero.
DATA ANAGRAFE; INPUT NOME $ COGNOME $ NATO_IL $ SESSO $ REDDITO FIGLI TITOLO; IF FIGLI=0 THEN DELETE; CARDS; Mario Aloia 16/10/52 M 32000000 1 Marco Bianchi 15/08/50 M 26000000 0 Elia Biorci 15/08/50 M 27000000 1 Anna Neri 22/11/60 F 80000000 5 Gina Rossi 11/05/56 F 25000000 2 Licia Saba 15/08/65 F 6500000 2 Enzo Verdi 12/08/62 M 35000000 1 Guido Zini 5/08/46 M 15000000 1 ; PROC PRINT DATA=ANAGRAFE; RUN;

1 2 1 0 2 3 1 1

Le osservazioni vengono regolarmente lette con la dichiarazione INPUT e i valori delle variabili portati nel PDV. La dichiarazione IF condiziona l'esecuzione della DELETE: solo quando verificata la condizione che il valore di FIGLI uguale a zero verr interrotta l'esecuzione del passo di DATA e ricomincer un nuovo ciclo partendo dalla prima dichiarazione eseguibile (la INPUT). Prima di ci viene reinizializzato il PDV, e non viene scritta nessuna osservazione nell'archivio di uscita. Il successivo passo PROC non trover nell'archivio ANAGRAFE l'osservazione relativa a MARCO BIANCHI (non ha figli) che quindi non verr stampata. Lo stesso risultato potrebbe essere ottenuto utilizzando la dichiarazione IF subsetting la cui sintassi : 78

IF <espressione condizionale>; Attenzione a non confondere questa dichiarazione con la IF-THENELSE. La dichiarazione IF subsetting non pu avere la parola chiave THEN mentre nella IF-THEN-ELSE la parola THEN obbligatoria. L'espressione condizionale prevista dalla IF subsetting segue le stesse regole di quella della IF-THEN-ELSE. Tutte le volte che la espressione condizionale specificata risulta vera viene eseguita la dichiarazione immediatamente seguente (se ne esiste una); quando invece la condizione risulta falsa, viene provocata una interruzione identica a quella provocata dalla dichiarazione DELETE. Il sistema SAS ricomincia l'esecuzione del passo di DATA senza scrivere nessuna nuova osservazione e reinizializzando il PDV. Il programma che segue assolutamente equivalente a quello precedente (notare che le condizioni sono contrarie: la dichiarazione DELETE infatti indica quando dobbiamo "eliminare", la IF subsetting invece indica quando dobbiamo "prendere").
DATA ANAGRAFE; INPUT NOME $ COGNOME $ NATO_IL $ SESSO $ REDDITO FIGLI TITOLO; IF FIGLI=0; CARDS; Mario Aloia 16/10/52 M 32000000 1 Marco Bianchi 15/08/50 M 26000000 0 Elia Biorci 15/08/50 M 27000000 1 Anna Neri 22/11/60 F 80000000 5 Gina Rossi 11/05/56 F 25000000 2 Licia Saba 15/08/65 F 6500000 2 Enzo Verdi 12/08/62 M 35000000 1 Guido Zini 5/08/46 M 15000000 1 ; PROC PRINT DATA=ANAGRAFE; RUN;

1 2 1 0 2 3 1 1

In questo caso si dovuto cambiare la condizione "=" con la condizione contraria "=". La dichiarazione DELETE infatti ha il compito di eliminare le osservazioni non volute mentre la IF subsetting ha il compito di mantenere le osservazioni che interessano. Si noti che nel programma precedente, quando la condizione specificata nella IF subsetting verificata, il sistema SAS passerebbe ad eseguire la dichiarazione immediatamente seguente. Poich non ne esiste nessuna (CARDS non una dichiarazione eseguibile), il contenuto del PDV viene scritto sull'archivio SAS di uscita, e comincia un nuovo ciclo di esecuzione del passo di DATA. 79

2.18.

La dichiarazione OUTPUT

Abbiamo visto fino a questo punto il tipico modo ciclico di eseguire un passo di DATA: inizializzazione del PDV, esecuzione di tutte le dichiarazioni del passo, scrittura del PDV nell'archivio di uscita (o archivi, se nella dichiarazione DATA ne sono specificati pi di uno) e di nuovo inizializzazione del PDV, ecc. (cfr. figura 2.8). In particolare la scrittura del PDV verr fatta automaticamente ad ogni passo di DATA senza che noi dobbiamo scrivere nulla di specifico e senza che noi possiamo intervenire. Con la dichiarazione OUTPUT tale automatismo viene inibito ed il compito di specificare quando e su quali archivi devono essere fatte le operazioni di scrittura, viene affidato al programmatore. Quando compare cio nel passo di DATA una dichiarazione OUTPUT, il sistema SAS non effettuer pi le operazioni di scrittura automatiche a fine passo, ma le effettuer solo quando la dichiarazione OUTPUT viene eseguita (anche questa una dichiarazione eseguibile). Dopo l'esecuzione della dichiarazione OUTPUT il sistema SAS prosegue normalmente l'esecuzione delle dichiarazioni che seguono. La sintassi della dichiarazione OUTPUT : OUTPUT [<nome archivio SAS>] [<nome archivio SAS>] ...... ; Se non viene specificato nessun archivio SAS, il contenuto del PDV viene copiato su tutti gli archivi di uscita elencati nella dichiarazione DATA; alternativamente si possono indicare esplicitamente gli archivi su cui scrivere, che possono essere scelti fra quelli elencati dopo la dichiarazione DATA. L'esempio che segue chiarisce ulteriormente quanto detto.
DATA FEMMINE MASCHI ERRORI; INPUT NOME $ COGNOME $ FIGLI TITOLO; IF SESSO='F' IF SESSO='M' IF SESSO='F' & SESSO = CARDS; Mario Aloia 16/10/52 Marco Bianchi 15/08/50 Elia Biorci 15/08/50 Walter Chiari 12/03/42 Guido Fusi 26/02/54 Ada Mori 27/05/57 Anna Neri 22/11/60 Gina Rossi 11/05/56 Licia Saba 15/08/65 Enzo Verdi 12/08/62 Guido Zini 5/08/46 RUN; NATO_IL $ SESSO $ REDDITO THEN OUTPUT FEMMINE; THEN OUTPUT MASCHI; M THEN OUTPUT ERRORI; M M * M M F F F F M M 32000000 26000000 27000000 95000000 35000000 40000000 80000000 25000000 . 35000000 . 1 0 1 0 3 0 5 2 2 1 1 1 2 1 4 2 1 0 2 3 1 1

In questo esempio suddividiamo i dati di ingresso in tre archivi separati basandoci sul valore della variabile SESSO. 80

Quando ad esempio il valore di SESSO 'F' il contenuto del PDV verr scritto solamente nell'archivio di nome FEMMINE, in quanto alla fine del passo di DATA non vengono fatte scritture automatiche; inoltre una sola IF conterr la condizione vera, mentre gli altri due, che verranno comunque eseguiti, conterranno condizioni false. Le tre condizioni infatti, sono scritte in modo tale che solo una di esse risulter verificata per ogni riga di dati e, per ogni riga di dati ce ne sar sempre una vera. Per visualizzare il contenuto dei tre archivi SAS creati, sar sufficiente scrivere il seguente programma SAS:
PROC PRINT DATA=FEMMINE; PROC PRINT DATA=MASCHI; PROC PRINT DATA=ERRORI; RUN;

L'archivio FEMMINE conterr 4 osservazioni, l'archivio MASCHI 6, l'archivio ERRORI infine solo una.

2.19.

La dichiarazione LENGTH

Una delle differenze che contraddistingue il sistema SAS da molti altri linguaggi, consiste nel fatto che non si obbligati a dichiarare le caratteristiche di ogni variabile usata in un passo di DATA. Tuttavia, in determinati casi, pu essere utile specificare il numero di posizioni che il sistema SAS deve riservare nel PDV per memorizzare i valori delle variabili. In questo caso si deve utilizzare la dichiarazione LENGTH. La sintassi la seguente: LENGTH <lista di variabili > [ $ ] lunghezza <lista di variabili > [ $ ] lunghezza ........ ; dove: lista di variabili sono i nomi delle variabili a cui si vuole assegnare una lunghezza; $ indica che le variabili indicate precedentemente sono non numeriche; lunghezza una costante numerica che pu assumere un valore compreso fra 2 e 8 per variabili numeriche e fra 1 e 200 per le variabili non numeriche. La dichiarazione LENGTH non eseguibile e viene usualmente 81

utilizzata per assegnare determinate lunghezze a variabili non numeriche. In linea di massima non conveniente dichiarare variabili numeriche pi piccole di 8 posizioni per non andare incontro a problemi di troncamento. Tuttavia, quando si hanno variabili numeriche che assumono solo valori interi, e si debbono gestire grossi archivi, pu essere conveniente risparmiare dello spazio disco. In tali casi pu essere utile la seguente tabella, nella quale vengono indicati i valori interi massimi, che sono rappresentati esattamente per le varie lunghezze. NPosizioni Massimo numero intero rappresentabile correttamente
2 3 4 5 6 7 8 255 65.535 16.777.215 4.294.967.295 1.099.511.627.775 281.474.946.710.655 72.057.594.037.927.935

Se usata per specificare lunghezze relative a variabili numeriche, la LENGTH pu trovarsi in qualunque punto di un passo di DATA; se usata invece per specificare lunghezze relative a variabili non numeriche, essa deve comparire prima che la variabile a cui si riferisce compaia la prima volta. Ad esempio il seguente passo di DATA:
DATA ESEMPIO; INPUT NOME $ ETA; LENGTH NOME $ 20 ETA 2; CARDS; MASSIMILIANO 30 ;

assegna alla variabile NOME solamente 8 posizioni, troncando il nome "MASSIMILIANO" a "MASSIMIL", e riserva alla variabile ETA 2 posizioni (si pu essere ragionevolmente certi che il contenuto della variabile ETA sia sempre minore di 255!). Invece il seguente passo di DATA:
DATA ESEMPIO; LENGTH NOME $ 20 ETA 2; INPUT NOME $ ETA; CARDS; MASSIMILIANO 30 ;

assegna nell'archivio SAS di uscita 20 posizioni alla variabile NOME ed ancora due posizioni alla variabile ETA. 82

In modo analogo, per modificare la lunghezza di variabili lette da un archivio SAS, si deve specificare la dichiarazione LENGTH prima della dichiarazione che legge l'archivio SAS. Proviamo ad esempio a modificare nell'archivio SAS ESEMPIO, prima creato, la lunghezza della variabile NOME da 20 a 30 caratteri; si deve eseguire il seguente passo di DATA:
DATA NUOVO; LENGTH NOME $ 30 ; SET ESEMPIO; RUN;

In assenza della dichiarazione LENGTH il sistema SAS determina la lunghezza di una variabile prendendo le informazioni dalla dichiarazione del passo di DATA nella quale la variabile compare la prima volta. Ad esempio il seguente programma SAS:
DATA PERSONE; INPUT SESSO $1. ; IF SESSO = 'M' THEN PERSONA = 'UOMO' ; ELSE IF SESSO = 'F' THEN PERSONA = 'DONNA'; ELSE PERSONA = 'NONSISA'; CARDS;

M F N ; PROC PRINT; TITLE 'ESEMPIO DI LUNGHEZZA IMPLICITA'; RUN;

darebbe la seguente uscita:


ESEMPIO DI LUNGHEZZA IMPLICITA OBS 1 2 3 SESSO M F N PERSONA UOMO DONN NONS

Come si vede "DONNA" viene troncato in "DONN" e "NONSISA" in "NONS" in quanto la lunghezza della variabile PERSONA stata impostata a 4 posizioni (pari al numero di caratteri della costante "UOMO"). E' opportuno in questo caso usare la dichiarazione LENGTH prima che la variabile PERSONA venga definita, come mostrato nell'esempio che segue. 83

DATA

PERSONE; INPUT SESSO $1. ; LENGTH PERSONA $ 8 ; IF SESSO = 'M' THEN PERSONA = 'UOMO' ; ELSE IF SESSO = 'F' THEN PERSONA = 'DONNA'; ELSE PERSONA = 'NONSISA'; CARDS;

M F N ; PROC PRINT; RUN;

L'uscita della PROC PRINT ora la seguente:


OBS 1 2 3 SESSO M F N PERSONA UOMO DONNA NONSISA

2.20. Qualche regola per una buona scrittura dei programmi


Come gi accennato in precedenza nello scrivere programmi utile osservare certe regole di "buona scrittura" per permettere una facile e veloce messa a punto e rendere possibile una manutenzione successiva del programma. Spesso infatti al mutare delle esigenze (entrano in vigore nuove leggi, cambiano le condizioni dell'azienda per cui stata scritta una procedura, ecc.) occorre apportare piccole variazioni ad un programma gi scritto. Il programmatore incaricato delle modifiche si trova allora nella necessit di localizzare i punti del programma da cambiare e le variabili che contengono i valori da utilizzare nei calcoli. Deve insomma capire il funzionamento del programma da una semplice lettura. Non sempre chi deve apportare modifiche l'autore del programma, e anche quando lo , verosimilmente il tempo intercorso tra la scrittura del programma e l'esigenza di variarlo sufficiente a far dimenticare il ragionamento seguito nella scrittura. Un metodo per facilitare la lettura di un programma quello di inserire via via dei commenti. Nella programmazione, per commento si intende una parte di testo utile al programmatore come spiegazione di certe operazioni, ma che non ha nessuna influenza nel funzionamento del programma in quanto viene ignorato in fase di traduzione. Per indicare (sia al sistema che al programmatore) che un testo deve essere considerato un 84

commento, si possono utilizzare nel sistema SAS due diverse sintassi. 1. La prima sintassi stabilisce che un commento sia iniziato con i caratteri /* (barra asterisco) e sia terminato con */ (asterisco barra) come stato fatto nel seguente esempio:
... INPUT A B C; /* coefficienti di una equazione DELTA=B**2-4*A*C; /* Calcolo del delta X1=(-B-SQRT(DELTA))/2*A; /* I radice dell'equazione X2=(-B+SQRT(DELTA))/2*A; /* II radice dell'equazione ... */ */ */ */

I commenti scritti in questo modo possono stare in ogni punto dove lecito inserire uno spazio (ad esempio all'interno delle dichiarazioni tra una parola e l'altra, ma non in mezzo ad una parola). 2. La seconda maniera di indicare un commento consiste nell'iniziarlo con * (asterisco) e terminarlo con ";" (punto e virgola). Questo secondo tipo di commenti ammesso solo tra una dichiarazione e l'altra ma non in mezzo alle istruzioni. In certi programmi "vecchi" si pu trovare la dichiarazione "COMMENT" al posto dell'asterisco. Vediamo un esempio:
... * lettura dei coefficienti di una equazione; INPUT A B C; COMMENT Calcolo del delta; DELTA=B**2-4*A*C; X1=(-B-SQRT(DELTA))/2*A; /* I radice dell'equazione */ X2=(-B+SQRT(DELTA))/2*A; /* II radice dell'equazione */ ...

Questo secondo tipo di commenti molto usato in fase di messa a punto del programma per rendere temporaneamente inefficaci alcune dichiarazioni e permettere la prova solo delle dichiarazioni di dubbia correttezza. Nell'esempio che segue abbiamo "commentato" (trasformato in commento) la terza dichiarazione che non verr pi considerata tale dal sistema.
... INPUT A B C; DELTA=B**2-4*A*C; * X1=(-B-SQRT(DELTA))/2*A; /* I radice dell'equazione */ X2=(-B+SQRT(DELTA))/2*A; /* II radice dell'equazione */ ...

L'uso dei commenti non sufficiente a rendere chiaro un programma se non accompagnato da un certo stile nella scrittura.

85

Questo fu messo in risalto da alcuni studiosi che nei primi anni settanta misero a punto una metodologia per la scrittura dei programmi conosciuta con il nome di programmazione strutturata. Tale metodologia si basa sull'osservazione che alcuni tipi di dichiarazione rendono difficoltosa la comprensione di un programma. Ad esempio la dichiarazione GO TO (cfr. paragrafo 4.3.3), se utilizzata in abbondanza, rende difficile la lettura di un programma perch costringe il programmatore a "saltare" continuamente in parti diverse del codice. E' stato dimostrato che questo tipo di dichiarazioni non indispensabile, in quanto esistono altre strutture pi comprensibili che permettono di ottenere gli stessi effetti. Le principali strutture consigliate sono la struttura "DO-END" iterativa (trattata nel capitolo 4), la struttura "IFTHEN-ELSE" e la struttura "CASE" (tradotta con la dichiarazione SELECT nel sistema SAS ). Poich non possibile entrare nel dettaglio della programmazione strutturata, ci limiteremo ad elencare alcune regole pratiche che sarebbe utile seguire nella scrittura di programmi: suddividere passi DATA complessi in pi passi elementari; usare nomi di variabili significativi anzich sigle poco chiare; non scrivere pi di una dichiarazione per riga; cominciare eventuali righe continuazione ad un margine spostato a destra di qualche colonna per evidenziare che esse fanno parte di una unica dichiarazione. Questa tecnica conosciuta con il nome di indentation. Il seguente esempio mostra una dichiarazione scritta su pi righe:
INPUT NOME $20. COGNOME $30. VIA $30. N_CIVIC $7. LOCALITA $30. TELEFONO $20. CAP $5. CITTA $20. PROV $2. STATO $15.;

evidenziare i vari passi che compongono il programma e le strutture di programmazione usate ("IF-THEN-ELSE", "DOEND", ecc.) con la tecnica dell'indentation; inserire nel programma commenti che indichino le parti significative di esso senza tuttavia eccedere, in quanto troppi commenti potrebbero interrompere la lettura delle dichiarazioni e risultare un impaccio anzich essere di aiuto. Inizialmente pu sembrare una pignoleria inutile attenersi a queste regole, tanto che anche alcuni programmatori professionisti non se ne curano credendo di risparmiare tempo; ma chi ha provato a seguirle si invece reso conto del grande risparmio di tempo che comporta scrivere programmi in maniera "elegante" e magari accompagnata da un tocco personale. 86

3. Il passo di PROC

3.1.

Generalit

Nel capitolo precedente sono state analizzate le componenti fondamentali di un passo di DATA. Nel presente capitolo faremo lo stesso per quanto riguarda il passo di PROC. Utilizzeremo per i primi esempi l'archivio ANAGRAFE che viene creato con il passo di DATA mostrato in figura 3.1.
DATA ANAGRAFE; INPUT NOME $ 1-8 COGNOME $ 10-18 NATO_IL $ 21-30 SESSO $ 34 REDDITO 37-45 FIGLI 49-50 TITOLO 53-54; CARDS; Mario Aloia 16/10/1952 M 32000000 1 1 Marco Bianchi 15/08/1975 M 26000000 0 2 Elia Biorci 15/08/1950 M 27000000 1 1 Walter Chiari 12/03/1942 M 95000000 0 4 Guido Fusi 26/02/1954 M 35000000 3 2 Ada Mori 27/05/1957 F 40000000 0 1 Anna Neri 22/11/1960 F 80000000 5 0 Gina Rossi 11/05/1956 F 25000000 2 2 Licia Saba 15/08/1965 F 36500000 2 3 Enzo Verdi 12/08/1962 M 35000000 1 1 Guido Zini 5/08/1946 M 15000000 1 1 RUN;

Figura 3.1: Passo di DATA che crea l'archivio SAS ANAGRAFE Supponiamo di dover eseguire le seguenti elaborazioni sull'archivio ANAGRAFE: stampa dei dati; calcolo e stampa della somma di tutti i redditi; ricerca e stampa del reddito massimo e di quello minimo. Questo semplice esercizio pu essere risolto utilizzando due diverse metodologie: si eseguono uno o pi passi di DATA che, partendo dall'archivio ANAGRAFE, producono i risultati richiesti. 87

Con questo tipo di approccio, tipico di un utente che possiede esperienza di programmazione, viene utilizzata la sola componente linguaggio del sistema SAS; si ricercano nelle librerie del sistema SAS dei programmi gi preconfezionati, che prendono il nome di "procedure" o "PROC", in grado di risolvere il problema; spesso, come in questo caso, vi sono addirittura diverse procedure fra cui un utente pu scegliere. Questo approccio tipico dell'ambiente SAS perch permette, anche ad un utente che non abbia una specifica esperienza, di dedicarsi interamente al problema da risolvere. Egli dovr solo individuare nelle librerie SAS quale procedura soddisfa le proprie esigenze e dovr imparare ad usarla. La quasi totalit delle procedure prelevano i dati da elaborare esclusivamente da archivi di tipo SAS; questo significa che prima di poter utilizzare una procedura si rende necessario creare un archivio SAS con un passo di DATA oppure in modo interattivo per mezzo della PROC FSEDIT, che verr descritta nel capitolo 9. Successivamente una qualunque procedura, sia essa appartenente alla parte generale del sistema SAS o ad un'altra componente specializzata quale ad esempio SAS/GRAPH, SAS/FSP ecc., potr elaborare l'archivio SAS che abbiamo creato. Questa caratteristica garantisce una perfetta integrazione di tutto il "mondo SAS" che, in questo senso, spesso schematizzato come un microcosmo il cui centro costituito dal SAS Base, che contiene il linguaggio e circa 70 procedure e la cui periferia costituita da componenti specializzate, ciascuna delle quali comprende a sua volta procedure aggiuntive (cfr. la figura 1.1 del capitolo 1). Ogni procedura deve essere richiamata all'interno di un passo di PROC; il passo di DATA ed il passo di PROC costituiscono gli unici componenti di un programma SAS. Non esiste alcuna limitazione su come deve essere composto un programma SAS, n sull'ordine con cui i singoli passi devono essere specificati. Possono esistere programmi composti solamente da passi di PROC, oppure solamente da passi di DATA, o infine da entrambi. La figura 3.2 mostra una possibile soluzione dell'esercizio proposto.
PROC PROC RUN; PRINT DATA=ANAGRAFE; SUM REDDITO; MEANS DATA=ANAGRAFE MIN MAX ; VARIABLES REDDITO;

Figura 3.2: Programma SAS composto di 2 passi di PROC 88

Si tratta di un programma SAS costituito da due passi di PROC: il primo richiama la procedura PRINT, che effettua la stampa dell'archivio ed esegue la somma dei redditi, mentre il secondo richiama la procedura MEANS, con la quale si ottengono il reddito massimo e quello minimo. La figura 3.3 mostra l'uscita prodotta dal precedente programma.
OBS NOME 1 2 3 4 5 6 7 8 9 10 11 Mario Marco Elia Walter Guido Ada Anna Gina Licia Enzo Guido COGNOME Aloia Bianchi Biorci Chiari Fusi Mori Neri Rossi Saba Verdi Zini NATO_IL 16/10/1952 15/08/1950 15/08/1950 12/03/1942 26/02/1957 27/05/1957 22/11/1960 11/05/1956 15/08/1965 12/08/1962 5/08/1946 SESSO REDDITO M M M M M F F F F M M 32000000 26000000 27000000 95000000 35000000 40000000 18000000 25000000 6500000 35000000 15000000 ========= 354500000 FIGLI TITOLO 1 0 1 0 3 0 5 2 2 1 1 1 2 1 4 2 1 0 2 3 1 1

VARIABLE

MINIMUM VALUE 6500000.00000

MAXIMUM VALUE 95000000.0000

REDDITO

Figura 3.3: Uscita prodotta dal programma di figura 3.2 Come si vede, le informazioni che abbiamo dovuto fornire alle due PROC sono ridotte al minimo e sono molto intuitive: il nome dell'archivio SAS da elaborare; le statistiche da calcolare; i nomi delle variabili interessate. Le procedure sono parte integrante del sistema SAS ed hanno la caratteristica di essere richiamate in tutti gli ambienti operativi su cui il sistema SAS implementato (mainframe, minicalcolatori e personal), richiedendo in ingresso le stesse informazioni e fornendo in uscita i medesimi risultati. Proprio al fine di garantire la totale indipendenza delle procedure dai vari sistemi operativi, SAS Institute Inc. sta gradualmente convertendo in linguaggio C tutte le procedure gi esistenti, che originariamente erano scritte in svariati linguaggi (ASSEMBLER, FORTRAN, PL/I, ecc.) . Oltre alle procedure contenute nelle librerie standard del sistema SAS e direttamente mantenute da SAS Institute Inc., esistono numerose altre procedure che vari utenti hanno sviluppato in modo autonomo e che riguardano un'ampia gamma di applicazioni. Le

89

procedure pi importanti e ritenute di interesse generale sono rese disponibili a tutti gli utenti SAS1. Tutte le procedure sono personalizzabili per mezzo di parametri che le rendono estremamente flessibili; non invece possibile apportare modifiche al loro funzionamento, per esempio aggiungendo o alterando qualche funzione, in quanto non sono disponibili i programmi sorgente relativi alle procedure stesse. Per superare questo ostacolo e per venire incontro alle esigenze degli utenti, SAS Institute Inc. conduce con cadenza annuale una indagine fra tutti gli utilizzatori del prodotto (denominata SASware Ballot), al fine di capire quale sia la necessit di implementare nuove funzioni. Per ogni settore applicativo (statistica, grafica, data base, econometria, ecc.) del sistema SAS, viene stilata una graduatoria delle domande di modifica pervenute, quali ad esempio inserimento di nuove procedure, variazioni ed ampliamenti a procedure esistenti ecc.. La richiesta di modifica, che in ciascun settore ha raccolto il maggior numero di preferenze, viene automaticamente accettata da SAS Institute Inc. che si impegna a realizzarla in successive versioni del sistema SAS.

3.2.

Classificazione delle procedure

Ci limiteremo in questa classificazione alle sole procedure comprese nella parte base del sistema SAS, tenendo presente che risulta molto difficile catalogarne alcune, il cui il campo di azione si presenta ad ampio spettro. Ad esempio la PROC TABULATE, che verr trattata in dettaglio nel capitolo 6, viene di solito considerata nella documentazione del sistema SAS, come una procedura di tipo statistico in quanto permette di calcolare statistiche descrittive in tabelle gerarchiche. Ma proprio per questa possibilit di costruire tabelle totalmente personalizzabili, questa PROC fra le pi usate per la produzione di rapporti che richiedono una elevata qualit, per quanto concerne l'aspetto esteriore. Ci premesso, da un punto di vista applicativo, le procedure comprese nella parte base del sistema SAS si possono suddividere nelle seguenti tre aree: Statistica Produzione di rapporti Utilit

1Esse sono contenute in una libreria, la "SUPPLEMENTAL LIBRARY", che

viene distribuita con il nastro di installazione del sistema SAS. La documentazione di queste procedure contenuta in un manuale dal titolo "SUGI Supplemental Library User's Guide".

90

3.2.1. Le procedure statistiche


Come noto, il sistema SAS nato quasi 20 anni fa come una libreria di programmi prevalentemente statistici ed oggi universalmente riconosciuto come uno dei pi completi pacchetti esistenti in questo settore. Non deve stupire quindi che le procedure statistiche disponibili nel sistema SAS, che sono riservate ad una ristretta ma molto esigente classe di utenza, siano molto numerose. Per quanto riguarda gli obiettivi che questo libro si prefigge, sufficiente elencare i vari settori della statistica che vengono coperti. Le varie procedure possono essere suddivise nei seguenti 9 gruppi: Analisi di regressione Analisi di varianza Analisi di dati categoriali Analisi di discriminanti Analisi di clustering Analisi di sopravvivenza Statistiche descrittive Analisi multivariata Scoring Si deve anche ricordare che esiste una componente del sistema SAS, il SAS/ETS (abbreviazione di Econometrics and Time Series), che mette a disposizione delle procedure molto sofisticate che permettono di formulare dei modelli di serie storiche al fine di compiere analisi e previsioni in vari contesti applicativi, soprattutto in campo economico.

3.2.2. Le procedure per la produzione dei report


Le procedure appartenenti a questa categoria, mostrate in figura 3.4, si dividono nei seguenti 3 gruppi, in funzione del tipo di rapporti generati: 1. Stampe analitiche che mostrano tutti i dati di un archivio; 2. stampe sintetiche che analizzano i dati raggruppandoli in funzione di determinati criteri e calcolano per ogni gruppo statistiche descrittive quali somme, percentuali, medie ecc.; 3. stampe che producono uscite grafiche quali istogrammi bidimensionali, tridimensionali ecc.. Nella componente SAS/GRAPH, esistono due procedure, GCHART e GPLOT, pi potenti delle corrispondenti CHART e PLOT. 91

GR. PROC FORMS 1 PRINT

DESCRIZIONE Effettua la stampa su moduli prefincati (es. etichette) Effettua la stampa effettuando totalizzazioni, formattando automaticamente lo spazio disponibile, ecc. QPRINT Effettua la stampa sotto forma di tabelle a pi colonne CALENDAR Stampa dati di sintesi o di pianificazione mensile in un formato stile calendario TABULATE Stampa statistiche descrittive in tabelle gerarchiche di 1, 2, e 3 dimensioni CHART Esegue ideogrammi e istogrammi a 2 e 3 dimensioni IDPLOT Esegue grafici di punti ciascuno dei quali pu essere identificato con una stringa di caratteri PLOT Esegue grafici bidimensionali di 2 variabili e/o di 3 variabili ("contour plot" ) TIMEPLOT Grafica una o pi variabili su intervalli di tempo

Figura 3.4: Principali PROC per la produzione di rapporti

3.2.3. Le procedure di utilit


Le procedure appartenenti a questa categoria, mostrate in figura 3.5, si dividono in 5 gruppi: 1. gestione di archivi SAS: queste PROC permettono di stampare e modificare la parte dati e/o la parte descrittiva di un archivio SAS. Nella componente SAS/FSP, esistono altre due procedure, FSBROWSE e FSEDIT, che sono pi flessibili delle corrispondenti BROWSE ed EDITOR; 2. gestione di librerie SAS: queste PROC permettono di copiare, annullare, rinominare, proteggere con parole chiave gli archivi SAS contenuti nelle librerie ; 3. collegamento con altri prodotti: sono procedure che permettono di accedere direttamente dati residenti in vari data base o di convertire in files SAS dati pronti per essere elaborati da altri prodotti; 4. programmi di utilit per la gestione nastri e procedure alternative ai programmi di utilit disponibili con i sistemi operativi IBM, di uso pi semplice ed in qualche caso con potenzialit maggiori; 5. programmi di utilit vari che realizzano funzioni particolari di supporto all'utente.

92

Figura 3.5: Principali PROC di utilit GR. PROC BROWSE 1 CONTENTS DATASETS EDITOR CONTENTS COPY DATASETS BMDP DESCRIZIONE Permette in modo interattivo o batch operazioni di ricerca sulla parte dati di un archivio SAS Stampa la parte descrittiva di un archivio SAS Modifica la parte descrittiva di un archivio SAS e stampa la parte dati Effettua modifiche alla parte dati di un archivio SAS D informazioni sugli archivi SAS di una libreria Copia una intera libreria SAS o membri selezionati Permette la gestione dei membri di una libreria SAS Richiama un programma BMDP per analizzare dati di un archivio SAS e converte un archivio SAS in un archivio di tipo BMDP. Converte dati BMDP, DATA-TEXT, OSIRIS e SPSS in dati SAS Permette l'accesso ad un data base SYSTEM 2000 inviando comandi da ambiente SAS Trasferisce dati da SYSTEM 2000 a sistema SAS Trasferisce dati da sistema SAS a SYSTEM 2000 Trasporta archivi SAS fra sistemi operativi diversi Permette la gestione di un archivio OS partitioned Copia archivi OS partitioned contenenti moduli eseguibili residenti su dischi e/o nastri Rilascia lo spazio allocato ma non usato di un archivio OS su disco Gestisce librerie OS e VSE di programmi sorgenti Copia nastri interi o files da un nastro ad un altro Legge le informazioni contenute nelle standard label dei nastri in OS e CMS Aggiunge le osservazioni di un archivio SAS direttamente al termine di un altro archivio SAS Confronta i valori delle variabili di due archivi SAS elencandone le differenze Permette l'esecuzione di applicazioni guidate da menu Crea dei formati personalizzati dell'utente Elenca le opzioni attive in una installazione SAS Definisce la destinazione per le uscite delle PROC Ordina le osservazioni di un archivio SAS in modo crescente o decrescente in funzione dei valori di una o pi variabili Traspone un archivio SAS scambiandone le osservazioni in variabili e viceversa

CONVERT 3 QUEST S2K S2KLOAD XCOPY PDS PDSCOPY RELEASE 4 SOURCE TAPECOPY TAPELABEL APPEND COMPARE DISPLAY FORMAT OPTIONS PRINTTO SORT

TRANSPOSE

93

3.3.

Elementi costituenti un passo di PROC

Come gi si detto, ogni passo di PROC richiama un programma da eseguire. Esso inizia sempre con una dichiarazione PROC, e pu proseguire con una o pi dichiarazioni; alcune di esse sono specifiche della procedura richiamata, mentre altre sono comuni alla maggior parte delle PROC. Salvo esplicita avvertenza, l'ordine con cui vengono specificate le dichiarazioni all'interno di un passo di PROC non essenziale. La maggior parte delle procedure in grado di produrre risultati con la sola dichiarazione PROC e l'indicazione, implicita od esplicita, dell'archivio SAS da elaborare. Questa semplicit d'uso porta come conseguenza che il modo pi proficuo per imparare ad usare una procedura quello di provarla in modo interattivo, possibilmente su un archivio di ridotte dimensioni, specificando in prima battuta le sole opzioni e/o dichiarazioni obbligatorie, piuttosto che quello di dedicare molto tempo allo studio di pagine e pagine di opzioni possibili sul manuale di riferimento. Solo successivamente, l'utente potr verificare tutte le potenzialit che una determinata procedura consente, in funzione del particolare problema da risolvere. In questo libro verranno illustrate in dettaglio, per ogni procedura, solamente le opzioni ed istruzioni pi importanti e verranno evidenziate quelle che debbono essere specificate obbligatoriamente. Per ottenere l'elenco completo delle funzioni e delle opzioni di ogni procedura, si consiglia di fare uso, oltre che dei manuali specifici di ciascuna componente, anche della documentazione in linea a cui si accede digitando il comando HELP dalla riga comando in ambiente Display Manager System (cfr. appendice A).

3.3.1. La dichiarazione PROC


La sintassi della dichiarazione PROC la seguente: PROC <nome programma > [opzioni] ; dove: nome programma il nome della procedura SAS che si richiama. Usualmente un nome compreso nelle librerie standard del sistema SAS ma si pu trattare anche di una procedura scritta dall'utente2. opzioni sono delle specifiche che servono a personalizzare la procedura.
2 Le specifiche di come deve essere scritta una procedura di utente si trovano

nella pubblicazione "SAS Programmer's Guide for PL/I " e nel SAS Technical Report P-125 "Adding user-written programs to VSE SAS".

94

Una opzione che usualmente deve essere specificata quando si richiama una procedura che elabora archivi SAS, la seguente: DATA=<archivio SAS> dove: archivio SAS indica il nome dell'archivio i cui dati devono essere elaborati. Nel caso che questa opzione sia assente, verr elaborato l'ultimo archivio SAS creato nel corso della sessione interattiva o del programma batch. Quando il sistema SAS incontra una dichiarazione PROC, per prima cosa accerta l'esistenza della procedura richiamata. In caso affermativo, il controllo passa alla procedura stessa che effettua una verifica formale delle opzioni e/o dichiarazioni specificate. Se tutto risulta essere corretto, la procedura comincia ad elaborare i dati; se invece vengono riscontrati errori di sintassi, il passo di PROC non viene eseguito ed il controllo viene trasferito al passo successivo. Riprendiamo come esempio il programma SAS di figura 3.2. Esso si compone di due passi; il primo richiama la PROC PRINT che ha una opzione "DATA=ANAGRAFE" ed una dichiarazione aggiuntiva "SUM REDDITO;". In questo caso vengono effettuati i seguenti controlli: esistenza dell'archivio SAS ANAGRAFE nelle libreria WORK; congruit della dichiarazione SUM con la procedura PRINT; esistenza della ANAGRAFE; variabile REDDITO nell'archivio

congruit del tipo di variabile (deve essere numerica). La PROC MEANS viene presa in esame solo dopo la conclusione della PROC PRINT, e presenta 3 opzioni: "DATA=ANAGRAFE", "MIN", "MAX" ed una dichiarazione aggiuntiva "VARIABLES REDDITO;". In questo caso vengono effettuati i seguenti controlli: esistenza dell'archivio SAS ANAGRAFE nella libreria WORK; congruit delle opzioni MIN e MAX con la procedura MEANS; congruit della dichiarazione VARIABLES con la procedura MEANS; esistenza della ANAGRAFE; variabile REDDITO nell'archivio

congruit del tipo di variabile (deve essere numerica). 95

In modo analogo al passo di DATA, un passo di PROC termina quando viene incontrata: un'altra dichiarazione PROC; una dichiarazione DATA; una dichiarazione RUN; la fine del programma SAS segnalato dalla dichiarazione "ENDSAS;" o dalla dichiarazione " /* " . In questi casi, ogni altra dichiarazione che segue viene ignorata.

3.3.2. Le dichiarazioni VARIABLES e BY


Passiamo ora in rassegna alcune dichiarazioni che possono essere usate nel contesto della maggior parte delle procedure: VARIABLES o VAR <lista di variabili > ; Questa dichiarazione seleziona il sottoinsieme delle variabili dell'archivio SAS che debbono essere elaborate; i nomi delle variabili devono esistere nell'archivio SAS cos come sono specificate. Se la dichiarazione omessa, vengono elaborate tutte le variabili presenti nell'archivio SAS congrue con l'elaborazione richiesta. Cos ad esempio la PROC PRINT visualizzer tutte le variabili di un archivio, mentre la PROC MEANS calcoler le statistiche descrittive di tutte le variabili numeriche, ignorando quelle non numeriche. Consideriamo ad esempio il seguente passo di PROC:
PROC PRINT DATA=ANAGRAFE; VAR COGNOME NOME ; RUN;

Esso produrr un tabulato contenente, per ogni osservazione, i valori delle sole variabili COGNOME e NOME:
OBS COGNOME 1 2 3 4 5 6 7 8 9 10 11 NOME

Aloia Mario Bianchi Marco Biorci Elia Chiari Walter Fusi Guido Mori Ada Neri Anna Rossi Gina Saba Licia Verdi Enzo Zini Guido

Si noti che l'ordine di stampa delle variabili rispetta la sequenza con cui esse sono state specificate nella dichiarazione VAR e non 96

quella con cui sono memorizzate nell'archivio ANAGRAFE. Questo comportamento ribadisce un concetto generale: l'unica informazione relativa ai dati, che l'utente deve fornire a tutte le procedure che elaborano archivi SAS, quella di indicare le variabili su cui egli intende agire; sar compito del sistema SAS di calcolare la posizione relativa di ogni variabile all'interno delle osservazioni, di verificare se le variabili esistono, se sono consistenti con le richieste effettuate, ecc.. Come si vede lo sforzo richiesto all'utente minimo, e soprattutto il colloquio fra utente e sistema SAS avviene su un terreno comprensibile anche per chi sia del tutto sprovvisto di esperienza di programmazione. BY <lista di variabili > ; Questa dichiarazione risulta obbligatoria solamente nella PROC SORT in quanto definisce le variabili in base alle quali l'archivio deve essere ordinato. In tutte le altre procedure essa facoltativa e specifica che dovranno essere prodotti risultati distinti (tabulati, tabelle, grafici ecc.) per ciascun valore diverso assunto dalle variabili indicate nella lista. In questo caso l'archivio SAS deve di norma essere preventivamente ordinato per mezzo di una PROC SORT con lo stesso criterio con cui sono specificate le variabili nella dichiarazione BY. Ad esempio il seguente programma SAS:
PROC PROC SORT DATA=ANAGRAFE; BY SESSO; MEANS MEAN MIN MAX; BY SESSO; VAR REDDITO;

RUN;

fornisce in uscita i redditi medi, minimi e massimi separatamente per femmine e maschi.
VARIABLE MEAN MINIMUM VALUE MAXIMUM VALUE

---------------------- SESSO=F ------------------------REDDITO 22375000.0000 6500000.0000 40000000.0000

---------------------- SESSO=M ------------------------REDDITO 37857142.8571 15000000.0000 95000000.0000

97

3.3.3. Altre dichiarazioni di uso generale


Prima di cominciare ad esaminare in dettaglio le prime procedure, indispensabile introdurre alcune dichiarazioni che possono essere specificate ovunque in un programma SAS e che, per questo motivo, vengono spesso definite come "dichiarazioni globali". TITLE si usa per specificare fino a 10 linee di titoli che saranno stampate in cima ad ogni pagina dei tabulati prodotti dal sistema SAS.

FOOTNOTE si usa per specificare fino a 10 linee di note che saranno stampate in fondo ad ogni pagina dei tabulati prodotti dal sistema SAS. OPTIONS si usa per dare al sistema SAS specifiche che sostituiscono, nel corso del programma, quelle stabilite al momento della installazione o in apertura della sessione SAS.

Le prossime due dichiarazioni possono essere specificate sia all'interno dei passi di DATA che dei passi di PROC. Esse sono: LABEL si usa per associare una etichetta ad una variabile, al fine di rendere maggiormente leggibili i risultati prodotti dalle diverse procedure. si usa per associare ad una variabile un "formato", cio un filtro o una maschera che definisce come i valori di quella variabile (non il nome della variabile come nella dichiarazione LABEL!) devono essere presentati in uscita.

FORMAT

Ecco in dettaglio la sintassi delle dichiarazioni: TITLE[n] ['titolo' ] ; dove: n segue immediatamente la parola TITLE; pu variare da 1 a 10 e specifica il numero della linea dove deve essere stampato il titolo. Ad esempio TITLE5 specifica la quinta linea dall'inizio della pagina. Se n non specificato equivale ad 1; ci significa che le due istruzioni: TITLE e TITLE1 sono equivalenti. 'titolo' il titolo da stampare, lungo fino a 132 caratteri, che deve essere racchiuso fra apici.

98

Il titolo indicato in una dichiarazione TITLEn continua ad essere riprodotto sulla n-sima riga di tutte le pagine di stampa generate nei successivi passi di DATA e/o di PROC, fino al termine della sessione SAS o fino a che venga specificata un'altra dichiarazione TITLEn relativa alla stessa linea o ad una linea con "n" minore. In altre parole il contenuto di una dichiarazione TITLEn sostituir quello di una precedente dichiarazione TITLEn relativa alla stessa linea ed annuller tutti i precedenti titoli relativi a linee con "n" maggiore. Cos per annullare tutti i titoli definiti in precedenza sar sufficiente specificare la dichiarazione "TITLE;"; lo stesso risultato si pu ottenere anche per mezzo della opzione NOTITLES da specificarsi nella dichiarazione FILE (cfr. capitolo 6). Il seguente programma:
PROC PRINT DATA=ANAGRAFE; TITLE 'STAMPA DELL''ARCHIVIO ANAGRAFE'; PROC MEANS DATA=ANAGRAFE MIN MAX ;

RUN;

stampa il titolo specificato nella prima linea di ogni pagina generata da entrambe le procedure. Il seguente programma:
PROC PRINT DATA=ANAGRAFE; TITLE 'TITOLO DI ESEMPIO'; TITLE2 'USCITA DELLA PROC PRINT'; TITLE3 'RELATIVA ALL''ARCHIVIO ANAGRAFE'; PROC MEANS DATA=ANAGRAFE MIN MAX ; TITLE2 'USCITA DELLA PROC MEANS'; RUN;

stampa le seguenti linee di intestazione, all'inizio di ogni pagina generata dalla PROC PRINT:
TITOLO DI ESEMPIO USCITA DELLA PROC PRINT RELATIVA ALL'ARCHIVIO ANAGRAFE

e le seguenti, all'inizio di ogni pagina prodotta dalla PROC MEANS:


TITOLO DI ESEMPIO USCITA DELLA PROC MEANS

Si noti che per stampare un apice nel testo (es "ALL'ARCHIVIO"), se ne devono specificare due nella dichiarazione TITLE.

99

FOOTNOTE[n] ['nota' ] ;

valgono le stesse considerazioni fatte per la dichiarazione TITLE. OPTIONS opzioni ;

dove: opzioni sono una o pi specifiche che si vogliono temporaneamente modificare. Il sistema SAS necessita, per poter lavorare, di una serie di specifiche o opzioni che sono stabilite al momento della installazione del prodotto ma che possono essere modificate in un qualunque momento durante una sessione o un programma SAS. Per conoscere quali sono i valori assegnati in fase di installazione alle varie opzioni del sistema SAS, esiste una procedura, la OPTIONS, che verr esaminata in seguito. La modifica permanente delle opzioni, specificate in fase di installazione, possibile con la PROC SETINIT. La modifica temporanea delle opzioni pu avvenire a due livelli: alcune devono essere specificate al momento in cui si richiama il sistema SAS (ad esempio se si vuole lavorare in ambiente Display Manager System o se si vuole attivare la componente macro del sistema SAS); altre invece possono essere specificate tramite la dichiarazione OPTIONS e mantengono la loro validit: fino al termine della sessione SAS se si lavora in modo interattivo; fino al termine del programma SAS se si lavora in ambiente batch; fino a quando il sistema SAS incontra un'altra dichiarazione OPTIONS con opzioni che modificano quelle specificate. Le opzioni pi comunemente usate sono le seguenti: FIRSTOBS=n specifica la prima osservazione che il sistema SAS deve elaborare; se non specificato altrimenti, FIRSTOBS uguale ad 1; in tal caso il sistema SAS comincia con la prima osservazione di un file. OBS=n specifica l'ultima osservazione che il sistema SAS deve elaborare; se non specificato altrimenti, OBS uguale a MAX; in tal caso il sistema SAS elabora tutte le osservazioni in un file. Se ad esempio si specifica:
OPTIONS FIRSTOBS=150 OBS=200;

100

ci significa che si vogliono elaborare solo le osservazioni comprese fra 150 e 200. Nel caso si voglia limitare il numero di record da elaborare in archivi non SAS, consigliabile specificare FIRSTOBS ed OBS come opzioni delle dichiarazioni INFILE relative (cfr. capitolo 5). LINESIZE=n ( o LS=n) definisce il numero massimo di posizioni disponibili su ogni riga di stampa; questo valore verr utilizzato per la uscite prodotte su stampante da tutte le PROC . I valori possono variare da 64 a 255. TLINESIZE=n ( o TL=n) definisce il numero massimo di posizioni disponibili su ogni riga di stampa; questo valore verr utilizzato per la uscite prodotte su terminale da tutte le PROC, quando si lavora in modo interattivo . Il valore minimo 64. Di solito il valore iniziale 0 indicando che il sistema SAS pu utilizzare la massima capacit del terminale . PAGESIZE=n ( o PS=n) definisce il numero massimo di linee che dovranno comparire su ogni pagina di stampa prodotta dal sistema SAS. I valori possono variare da 20 a 500. CENTER/NOCENTER specifica se le uscite prodotte dalle procedure SAS debbono essere rispettivamente centrate nella pagina o allineate a sinistra. Il valore iniziale dipende dalla singola installazione. DQUOTE/NODQUOTE specifica se le costanti non numeriche debbono essere rispettivamente racchiuse fra doppi apici (ad esempio "CASA") o fra apici (ad esempio 'CASA'). L'opzione DQUOTE raccomandata nel caso si usi la componente Macro del sistema SAS (cfr. capitolo 8). Le opzioni che sono attive all'inizio di un passo di DATA o di PROC, mantengono la loro validit fino al termine del passo. Se all'interno di un passo presente una dichiarazione OPTIONS che specifica opzioni diverse, queste saranno prese in considerazione solo dal passo successivo. Consideriamo il seguente esempio:
OPTIONS PROC RUN; OPTIONS PROC RUN; OBS=5; PRINT DATA=ANAGRAFE; OBS=MAX; MEANS DATA=ANAGRAFE MIN ; VAR REDDITO ;

101

La PROC PRINT stampa le prime 5 osservazioni dell'archivio ANAGRAFE, mentre la PROC MEANS calcola il reddito minimo, considerando tutte le osservazioni. Se la prima dichiarazione "RUN;" viene posposta alla dichiarazione OPTIONS, cio:
OPTIONS PROC OPTIONS RUN; PROC RUN; OBS=5; PRINT DATA=ANAGRAFE; OBS=MAX; MEANS DATA=ANAGRAFE MIN ; VAR REDDITO ;

il sistema SAS considera la dichiarazione "OPTIONS OBS=MAX;" solo dopo che la PROC PRINT terminata; pertanto entrambi questi programmi SAS forniscono la medesima uscita, che viene mostrata in figura 3.6:
OBS NOME 1 2 3 4 5 Mario Marco Elia Walter Guido COGNOME Aloia Bianchi Biorci Chiari Fusi NATO_IL 16/10/1952 15/08/1950 15/08/1950 12/03/1942 26/02/1957 VARIABLE SESSO REDDITO M M M M M 32000000 26000000 27000000 95000000 35000000 MINIMUM VALUE 6500000.00000 FIGLI TITOLO 1 0 1 0 3 1 2 1 4 2

REDDITO

Figura 3.6: Uscita dei programmi SAS dei due esempi precedenti LABEL variabile = 'etichetta' ; dove: variabile il nome di una variabile a cui si vuole associare una etichetta. etichetta una stringa alfanumerica lunga fina a 40 caratteri, spazi compresi, che deve essere racchiusa fra apici (o doppi apici se valida la opzione DQUOTE). Se la dichiarazione si trova in un passo di DATA, l'etichetta viene memorizzata nell'area riservata alla parte descrittiva dell'archivio SAS creato; se invece la dichiarazione compare in un passo di PROC, l'etichetta viene associata alla variabile solo nel passo di PROC in cui compare, senza alterare la parte descrittiva dell'archivio. Questo meccanismo permette cos di avere memorizzate delle etichette in modo permanente, ma consente anche di poterne sovrapporre altre temporanee in qualsiasi momento.

102

La modifica delle etichette memorizzate in un archivio SAS pu avvenire in modo non interattivo, per mezzo di un passo di DATA nel quale si associano alle variabili nuove etichette, o in modo interattivo con la PROC DATASETS. E' senza dubbio consigliabile l'uso della PROC DATASETS soprattutto nel caso di archivi SAS di grosse dimensioni. Tale procedura infatti non solo molto semplice da usarsi, ma si dimostra anche molto pi efficiente in quanto non deve creare nessun nuovo archivio ma deve modificare la sola parte descrittiva dell'archivio esistente. Non sempre le procedure hanno lo stesso comportamento nei confronti delle etichette. Una prima differenza di comportamento rilevabile nel caso in cui la stampa della etichetta non rientri nelle dimensioni della pagina di stampa, che sono definite dalle opzioni LINESIZE e PAGESIZE. In tal caso, alcune procedure, come la MEANS, eliminano la stampa dell'etichetta; altre invece, come la PLOT, stampano comunque l'etichetta, troncando la parte che non rientra nella pagina. Un'altra differenza rilevabile nella PROC PRINT; in questa procedura la stampa delle etichette deve essere richiesta in modo esplicito (tramite l'opzione LABEL e/o SPLIT); in caso contrario le etichette non sono stampate, anche se nel passo di PROC esistono dichiarazioni LABEL. La maggior parte delle procedure SAS utilizzano poi le etichette per stamparle in sostituzione delle variabili; ma esistono alcune PROC, come ad esempio la MEANS, che visualizzano sia i nomi delle variabili che quello delle etichette ad esse associate. Riprendiamo l'esempio di figura 3.2 ed associamo una etichetta alle variabili NATO_IL e REDDITO come mostrato in figura 3.7.
PROC PRINT DATA=ANAGRAFE LABEL; SUM REDDITO; LABEL NATO_IL='DATA DI NASCITA'; MEANS DATA=ANAGRAFE MIN MAX ; VAR REDDITO; LABEL REDDITO='STIPENDIO LORDO';

PROC

RUN;

Figura 3.7: Esempio d'uso di dichiarazioni LABEL Questo programma produce l'uscita mostrata in figura 3.8. Si pu notare come in effetti nella PROC PRINT la etichetta "DATA DI NASCITA" sostituisce la variabile "NATO_IL", mentre nella PROC MEANS compaiono sia la variabile "REDDITO" che l'etichetta "STIPENDIO LORDO".

103

Da sottolineare infine la presenza della opzione LABEL nella PROC PRINT, senza la quale la stampa della etichetta non avverrebbe.
OBS NOME COGNOME DATA DI NASCITA SESSO REDDITO FIGLI TITOLO 1 2 3 4 5 6 7 8 9 10 11 Mario Marco Elia Walter Guido Ada Anna Gina Licia Enzo Guido Aloia Bianchi Biorci Chiari Fusi Mori Neri Rossi Saba Verdi Zini 16/10/1952 15/08/1950 15/08/1950 12/03/1942 26/02/1957 27/05/1957 22/11/1960 11/05/1956 15/08/1965 12/08/1962 5/08/1946 M M M M M F F F F M M 32000000 26000000 27000000 95000000 35000000 40000000 18000000 25000000 6500000 35000000 15000000 ========= 354500000 1 0 1 0 3 0 5 2 2 1 1 1 2 1 4 2 1 0 2 3 1 1

VARIABLE

LABEL

MINIMUM VALUE 6500000.00000

MAXIMUM VALUE 95000000.0000

REDDITO

STIPENDIO LORDO

Figura 3.8: Uscita del programma di figura 3.7 FORMAT <lista di variabili > formato ; dove: lista di variabili il nome di una o pi variabili a cui si vuole associare un formato. formato indica il formato attraverso cui devono essere filtrati i valori delle variabili indicati nella lista precedente; tale formato pu essere gi esistente nel sistema SAS, oppure pu essere costruito "su misura" dall'utente stesso per mezzo della PROC FORMAT. Ogni formato richiamato nel seguente modo: <nome formato > [c].[d] dove: nome formato uno dei nomi da scegliere fra un elenco di circa 50 gi esistenti nel sistema SAS3 oppure un nome precedentemente definito dall'utente all'interno di una PROC FORMAT (cfr. capitolo 6). Nel caso in cui la variabile associata al formato sia non numerica, obbligatorio specificare il carattere "$" prima del nome del formato.
3 La descrizione completa dei formati che possono essere richiamati si trova nel

manuale "SAS User's guide: Basics".

104

c il numero massimo di caratteri, ovvero di posizioni di stampa, di cui pu disporre il formato. In alcuni formati, ed in particolare in quelli definiti dall'utente, c pu essere omesso. In questi casi il sistema SAS assume un valore predefinito (di default); . il "." deve sempre essere specificato per evitare che il sistema SAS interpreti il nome del formato come quello di una variabile; d questa informazione facoltativa ed valida solo per variabili numeriche. Indica il numero massimo di decimali che debbono essere riservati all'interno delle "c" posizioni. Questa dichiarazione pu essere specificata sia in un passo di DATA che in uno di PROC. Se essa si trova in in passo di DATA, il formato viene memorizzato nella parte descrittiva dell'archivio SAS; se invece la dichiarazione compare in un passo di PROC, il formato mantiene la sua validit solo nel passo di PROC in cui compare, senza alterare la parte descrittiva dell'archivio. L'associazione di un formato ad una variabile non altera i valori della variabile nell'archivio SAS; il formato viene preso in esame dalla procedura solo al momento in cui il contenuto della variabile viene visualizzato. E' compito dell'utente scegliere un formato che sia significativo per la rappresentazione dei valori della variabile. E' interessante capire come si comporta il sistema SAS nel caso in cui le posizioni di stampa specificate nel formato non siano sufficienti per contenere il valore da stampare. Supponiamo ad esempio che il valore di una variabile numerica NUM sia 12345.67 mentre quello di una variabile non numerica CAR sia 'SALAMELECCO'. La figura 3.9 mostra come si modifica la stampa di questi dati, in funzione del formato specificato (rispettivamente "$c." per la variabile non numerica, "c.d " per quella numerica) al variare di c e di d. Se la variabile di tipo non numerico, essa viene stampata a partire da sinistra verso destra fino a riempire le c posizioni di stampa disponibili. Se il numero di caratteri della variabile maggiore del numero di posizioni di stampa disponibili, i caratteri in eccesso sulla destra non vengono visualizzati (caso 2 di figura 3.9). 105

Per le variabili numeriche il discorso pi complesso, ed il sistema SAS mostra tutta la sua flessibilit cercando di stampare "al meglio" il valore di una variabile numerica, anche contravvenendo alle disposizioni ricevute dall'utente. Infatti, se il valore di una variabile ha un numero di cifre decimali superiore alle d posizioni disponibili (caso 3 di figura 3.9), oppure ha globalmente un numero di caratteri che eccede il numero c di posizioni disponibili (casi 5, 6 e 7 di figura 3.9), il sistema SAS esegue degli arrotondamenti sulla parte decimale del numero da stampare, allineando il risultato a destra. Se poi le c posizioni disponibili risultano inferiori anche al numero di cifre intere della variabile numerica da stampare, il sistema SAS converte il valore della variabile in formato esponenziale, con il formato BESTc., eseguendo gli opportuni arrotondamenti, come viene evidenziato nel caso 8 della figura 3.9. In questo caso il sistema SAS sostituisce il formato BEST4. a quello specificato. Il numero rappresentato nella forma 12 moltiplicato 103, ovvero 12 moltiplicato 1000, cio 12000.
Caso Variabile
1 2 3 4 5 6 7 8 CAR CAR NUM NUM NUM NUM NUM NUM

Formato
$12. $6. 8.1 8.2 7.2 6.2 5.2 4.2

Risultato
SALAMELECCO SALAME 12345.7 12345.67 12345.7 12346 12346 12E3

Figura 3.9: Come variano i dati visualizzati al variare del formato

3.4. Visualizzazione delle opzioni correnti: PROC OPTIONS


Questa procedura elenca sul SASLOG i valori di tutte le opzioni (oltre 100!) globali di sistema, fornendo per ciascuna una breve descrizione. Se la procedura viene lanciata subito dopo essere entrati in una sessione SAS, essa visualizza i valori di inizializzazione (default) di ciascuna opzione cos come sono stati stabiliti al momento della installazione del sistema SAS. Se essa viene invece eseguita nel corso di una sessione SAS, vengono visualizzati i valori correnti delle opzioni al momento della esecuzione. La sintassi della procedura, che si compone della sola dichiarazione PROC, mostrata di seguito. PROC OPTIONS [opzioni ] ; 106

La principale opzione la seguente: SHORT richiede un elenco abbreviato delle opzioni. Se essa non viene specificata, il sistema SAS stampa ogni opzione su una riga diversa con una breve spiegazione del suo significato.

3.5. Ordinamento di un archivio: PROC SORT


Questa procedura esegue l'ordinamento delle osservazioni di un archivio SAS in funzione di una o pi variabili. L'unica uscita fornita dalla PROC SORT un messaggio sul SASLOG in cui viene specificato il numero di osservazioni e di variabili che compongono l'archivio ordinato. L'uso pi comune di questa procedura quello di ordinare un archivio SAS prima che questo venga trattato da altre procedure o da dichiarazioni (es.: SET e MERGE) che usano la dichiarazione BY. La sintassi della procedura la seguente: PROC SORT [opzioni ] ; Le principali opzioni sono le seguenti: DATA=<archivio SAS> il nome dell'archivio da ordinare. Se non specificato, il sistema SAS assume l'ultimo creato. OUT=<archivio SAS> il nome dell'archivio di uscita; se non specificato l'archivio ordinato si sovrappone a quello originale. Questa procedura ammette una sola dichiarazione, che deve sempre essere specificata: BY [DESCENDING] variabile [DESCENDING] variabile ....... ; in una dichiarazione BY si pu specificare un qualunque numero di variabili, sia numeriche che non numeriche. Se sono presenti pi variabili, tutte le osservazioni sono prima ordinate in funzione della prima variabile specificata dopo il BY. Successivamente, ogni gruppo di osservazioni aventi lo stesso valore della prima variabile ordinato in funzione della seconda variabile; questo processo continua fino ad esaurimento delle variabili specificate dopo il BY. Si noti che l'opzione DESCENDING viene usata per specificare al sistema SAS che la variabile che segue deve essere ordinata in 107

ordine decrescente; in sua assenza l'ordinamento avviene in ordine crescente. Ad esempio il seguente programma SAS:
PROC RUN; SORT DATA=ANAGRAFE OUT=ORDINATO; BY DESCENDING SESSO REDDITO;

effettuer un ordinamento decrescente delle osservazioni dell'archivio ANAGRAFE in funzione della variabile SESSO; verranno cos creati tanti gruppi quanti sono i valori diversi della variabile SESSO. Ogni gruppo sar successivamente ordinato in funzione crescente della variabile REDDITO. Al termine della procedura l'archivio ANAGRAFE rester inalterato e verr creato l'archivio ORDINATO; comparir inoltre sul SASLOG il seguente messaggio:
NOTE: THE DATA SET WORK.ORDINATO HAS 11 OBSERVATIONS AND 7 VARIABLES

Se si vuole stampare l'archivio ORDINATO, si dovr scrivere il seguente passo di PROC:

OPTIONS CENTER; PROC PRINT DATA=ORDINATO; TITLE 'STAMPA IN ORDINE DI SESSO E DI REDDITO'; RUN;

che produrr la seguente uscita :


STAMPA IN ORDINE DI SESSO E DI REDDITO OBS NOME 1 2 3 4 5 6 7 8 9 10 11 Guido Marco Elia Mario Guido Enzo Walter Licia Anna Gina Ada COGNOME Zini Bianchi Biorci Aloia Fusi Verdi Chiari Saba Neri Rossi Mori NATO_IL 5/08/1946 15/08/1950 15/08/1950 16/10/1952 26/02/1957 12/08/1962 12/03/1942 15/08/1965 22/11/1960 11/05/1956 27/05/1957 SESSO REDDITO M M M M M M M F F F F 15000000 26000000 27000000 32000000 35000000 35000000 95000000 6500000 18000000 25000000 40000000 FIGLI TITOLO 1 0 1 1 3 1 0 2 5 2 0 1 2 1 1 2 1 4 3 0 2 1

Nella stampa si nota che vi sono due osservazioni (la 5 e la 6), in cui la variabile REDDITO ha lo stesso valore. In tal caso stato mantenuto lo stesso ordinamento dell'archivio di ingresso ANAGRAFE. 108

3.6.

Visualizzazione di un archivio

Come ormai noto, un archivio SAS si compone di due distinte sezioni (cfr. figura 2.4 del capitolo 2): la parte descrittiva; la parte dati. La due componenti sono entit logicamente e fisicamente separate; mentre la parte descrittiva esiste sempre, possono essere creati archivi SAS nei quali la parte dati vuota. Esistono diverse procedure che danno informazioni sul contenuto di un file SAS; verranno in questo paragrafo esaminate in dettaglio le seguenti: PROC CONTENTS PROC PRINT che stampa il contenuto della parte descrittiva; che stampa il contenuto della parte dati.

Esiste nella componente base del SAS anche un'altra importante procedura, che non trattata in dettaglio in questo libro, ma che molto semplice da usare in quanto interattiva. Si tratta della PROC DATASETS, che visualizza su terminale la parte dati e permette di apportare modifiche ad alcuni elementi della parte descrittiva di un archivio SAS, come ad esempio il nome delle variabili, il contenuto delle etichette e dei formati. Non invece possibile con la PROC DATASETS modificare n il tipo, n la lunghezza delle variabili.

3.6.1. PROC CONTENTS


Per ogni archivio SAS vengono stampate, in assenza di opzioni particolari, le seguenti informazioni: nome dell'archivio SAS; dati relativi alla sua creazione (data, ora, modello di elaboratore, sistema operativo ecc.); spazio disco occupato dall'archivio SAS; numero di osservazioni e di variabili presenti nell'archivio SAS; elenco delle variabili in ordine alfabetico; lista delle dichiarazioni del passo di DATA utilizzate per creare l'archivio SAS (se stato creato con un passo di DATA). 109

Per ogni variabile vengono inoltre fornite le seguenti informazioni: nome della variabile; tipo ( numerica o non numerica); lunghezza; posizione relativa occupata nell'archivio; attributi della variabile (formato di lettura, formato di stampa, etichetta associata). La sintassi della procedura, che si compone della sola dichiarazione PROC, la seguente: PROC CONTENTS [opzioni ] ; Le principali opzioni sono le seguenti: DATA=libreria.membro specifica l'archivio SAS di cui deve essere stampata la parte descrittiva; per archivi temporanei, libreria pu essere omessa o deve essere codificato WORK. Se si vogliono stampare tutti i membri di una libreria, al posto del singolo membro si deve specificare _ALL_ . Ad esempio:
PROC CONTENTS DATA=WORK._ALL_ ;

visualizza le parti descrittive di tutti gli archivi temporanei creati durante un programma o una sessione SAS. SHORT viene fornito il solo elenco delle variabili. POSITION stampa una seconda lista di variabili ordinati in funzione della posizione occupata nell'archivio SAS. OUT=<archivio SAS> crea un archivio SAS contenente 18 variabili i cui nomi sono predefiniti e tante osservazioni quante sono le variabili dell'archivio originale. Ogni osservazione dell'archivio creato, contiene cos tutte le informazioni relative ad ogni variabile dell'archivio originale (tipo, lunghezza, etichetta associata, formati, ecc.) . Il programma SAS che segue permette ad esempio di vedere il contenuto della parte des crittiva dell'archivio SAS ANAGRAFE.

110

PROC CONTENTS DATA=ANAGRAFE; RUN;

L'uscita di questa procedura la seguente:


CONTENTS PROCEDURE CONTENTS OF SAS MEMBER WORK.ANAGRAFE CREATED BY CMS USERID EDOARDO ON CPUID FF-3081-001964 AT 11.26 TUESDAY, OCTOBER 20, 1987 BY SAS RELEASE 5.16 FILE= WORK ANAGRAFE BLKSIZE=8180 LRECL=56 GENERATED BY DATA NUMBER OF OBSERVATIONS: 11 NUMBER OF VARIABLES: 7 MEMTYPE: DATA ----ALPHABETIC LIST OF VARIABLES AND ATTRIBUTES----# VARIABLE TYPE LENGTH POSITION FORMAT INFORMAT LABEL 2 COGNOME CHAR 9 12 6 FIGLI NUM 8 40 3 NATO_IL CHAR 10 21 1 NOME CHAR 8 4 5 REDDITO NUM 8 32 4 SESSO CHAR 1 31 7 TITOLO NUM 8 48 ---------------------- SOURCE RECORDS --------------------| DATA ANAGRAFE; | | INPUT NOME $ 1-8 COGNOME $ 10-18 NATO_IL $ 21-30 | | SESSO $ 34 REDDITO 37-45 FIGLI 49-50 | | TITOLO 53-54; | | CARDS; | -----------------------------------------------------------

Vogliamo ora ottenere l'elenco delle sole variabili, sia in ordine alfabetico che nell'ordine con cui sono memorizzate nell'archivio SAS.
PROC CONTENTS DATA=ANAGRAFE SHORT POSITION; RUN;

L'uscita di questa procedura la seguente:


CONTENTS OF SAS MEMBER WORK.ANAGRAFE ----ALPHABETIC LIST OF VARIABLES AND COGNOME FIGLI NATO_IL NOME ----LIST OF VARIABLES AND ATTRIBUTES NOME COGNOME NATO_IL SESSO ATTRIBUTES----REDDITO SESSO TITOLO BY POSITION---REDDITO FIGLI TITOLO

3.6.2. PROC PRINT


Questa procedura visualizza tutte o alcune variabili di un archivio SAS. Alcune caratteristiche della procedura sono le seguenti: 111

viene eseguita in modo automatico la formattazione delle informazioni da stampare entro le dimensioni della pagina. Queste dimensioni sono calcolate in modo automatico dal sistema SAS esaminando i valori che, al momento della esecuzione della procedura, hanno le opzioni LINESIZE e PAGESIZE; le variabili sono stampate su colonne che sono identificate dal nome stesso della variabile o dalla etichetta ad essa associata; salvo indicazione contraria dell'utente, viene inoltre stampata una colonna identificata con "OBS" contenente un numero progressivo con cui vengono identificate le osservazioni. Si deve sottolineare che OBS non una variabile dell'archivio; le osservazioni sono stampate, quando possibile, una per riga; per risparmiare spazio la procedura pu decidere di stampare i nomi delle variabili che identificano le colonne verticalmente piuttosto che orizzontalmente. Se, nonostante questo artificio, a causa dell'eccessivo numero delle variabili o dell'esiguo numero di posizioni specificato in LINESIZE, non possibile contenere una osservazione su una riga, questa viene ripartita su pi righe. Per fare ci la pagina viene spezzata in due o pi sezioni, ciascuna delle quali contiene un sottoinsieme delle variabili di ogni osservazione; possibile effettuare totalizzazioni delle numeriche; variabili

la procedura ottimizza al massimo lo spazio della pagina cercando di stampare il maggior numero possibile di osservazioni e di variabili nello spazio disponibile. Ogni pagina pu venire cos formattata in modo diverso, con il risultato che la posizione delle colonne utilizzate per stampare le variabili pu differire da una pagina all'altra. La sintassi della procedura la seguente: PROC PRINT [opzioni ] ; Le principali opzioni sono le seguenti: DATA=<archivio SAS> specifica l'archivio SAS la cui parte dati deve essere visualizzata; se questo viene omesso il sistema SAS assume l'ultimo creato. DOUBLE (o D ) richiede la spaziatura doppia fra una riga e l'altra.

112

LABEL questa opzione deve essere specificata se si vogliono intestare le colonne con le etichette associate alle variabili. La specifica di questa opzione pu accrescere il numero di pagine necessarie per la stampa dell'archivio. Infatti, come gi detto, al fine di ottimizzare al massimo lo spazio a disposizione, la procedura pu decidere di stampare i nomi delle variabili verticalmente piuttosto che orizzontalmente. Se questa opzione specificata, ed almeno una variabile ha una etichetta associata, tutte le intestazioni delle colonne saranno stampate orizzontalmente. N richiede la stampa del numero di osservazioni al termine dell'archivio, oppure, se compare la dichiarazione BY, ogni volta che cambia il valore di una delle variabili specificate dopo il BY. ROUND richiede di arrotondare i valori numerici prima che essi siano totalizzati, in modo da evitare errori di arrotondamento nella somma. Questa opzione ha senso solo se richiesta una totalizzazione (dichiarazione SUM) di variabili numeriche nelle quali siano presenti cifre decimali. SPLIT='<carattere di separazione >' indica un carattere che compare nella etichetta associata al nome della variabile. Questo carattere non viene stampato, ma viene utilizzato per poter stampare l'etichetta su pi righe (tre al massimo). Quando questa opzione presente, diventa superfluo specificare l'opzione LABEL per ottenere la stampa delle etichette. Ad esempio:
OPTIONS OBS=3; PROC PRINT DATA=ANAGRAFE SPLIT='$' NOOBS; VAR NOME COGNOME FIGLI; LABEL FIGLI = 'NUMERO$DEI$FIGLI'; RUN;

produce la seguente uscita:


NOME COGNOME NUMERO DEI FIGLI 1 0 1

MARIO MARCO ELIA

ALOIA BIANCHI BIORCI

113

NOOBS elimina dalla stampa la colonna OBS, contenente la numerazione progressiva delle osservazioni. UNIFORM richiede che la posizione delle colonne sia mantenuta invariata su tutte le pagine. Per archivi contenenti molte variabili, questa opzione facilita notevolmente la leggibilit del tabulato prodotto. Le principali dichiarazioni della procedura sono le seguenti: BY <lista di variabili > ; indica che debbono essere effettuate analisi diverse, tipicamente totalizzazioni se specificata anche la dichiarazione SUM, per ciascun valore assunto dalle variabili indicate nella lista. L'archivio SAS deve essere preventivamente ordinato per mezzo di una PROC SORT con lo stesso criterio con cui sono specificate le variabili nella dichiarazione BY. ID <lista di variabili > ; le variabili specificate sostituiscono la colonna identificata con "OBS". PAGEBY variabile ; ordina alla PROC PRINT di andare a pagina nuova ogni volta che cambia il valore della variabile specificata, o di un'altra che fisicamente la precede in una dichiarazione BY; ad esempio il seguente passo:
PROC PRINT ; BY SESSO TITOLO ; PAGEBY TITOLO ;

RUN ;

causa un salto pagina ogni qualvolta cambia il valore della variabile SESSO o della variabile TITOLO. Se nella dichiarazione PAGEBY compare una variabile non specificata nella dichiarazione BY il sistema SAS segnala errore ed il passo non viene eseguito. SUM <lista di variabili > ; indica quali variabili numeriche debbono essere totalizzate; se presente anche una dichiarazione BY, la totalizzazione viene ripetuta ogni volta che cambia un valore di una delle variabili in essa elencate. Se vengono indicate variabili non presenti nella dichiarazione VAR, esse sono automaticamente aggiunte nella stampa. 114

VAR <lista di variabili > ; ha la doppia funzione, in questa procedura, di indicare quali variabili debbono essere visualizzate ed in quale ordine. Se omessa, vengono stampate tutte le variabili nell'ordine in cui sono state memorizzate nell'archivio SAS. SUMBY variabile ; va usata solo nel caso sia presente una dichiarazione SUM ed una BY con pi variabili; la variabile specificata deve comparire nella dichiarazione BY. Ogni volta che tale variabile, o un'altra che fisicamente la precede nella dichiarazione BY, cambiano valore, vengono stampati i totali delle variabili che sono specificate nella dichiarazione SUM. Estraiamo ad esempio dall'archivio ANAGRAFE tutte le osservazioni nelle quali il reddito risulta maggiore di 25 milioni.
DATA RICCHI; SET ANAGRAFE; IF REDDITO > 25000000;

RUN ;

Il programma mostrato in figura 3.10 :


PROC SORT DATA=RICCHI; BY SESSO TITOLO; PROC PRINT DATA=RICCHI NOOBS; BY SESSO TITOLO; SUMBY SESSO; SUM REDDITO; VAR NOME COGNOME REDDITO; RUN ;

Figura 3.10: Esempio di uso della dichiarazione SUMBY produce l'uscita riportata in figura 3.11. Come si vede dall'esame del tabulato, mancano i totali parziali ogni volta che cambia il valore della variabile TITOLO; questi totali sarebbero invece stampati in assenza della dichiarazione SUMBY, ovvero se essa fosse stata specificata come segue:
SUMBY TITOLO;

Nel corso del capitolo sono gi stati mostrati vari esempi di stampa dell'archivio ANAGRAFE che evidenziano alcune delle principali opzioni e dichiarazioni che la PROC PRINT permette. Come esempio finale risolviamo il seguente problema, cercando di utilizzare le procedure finora illustrate, cio SORT e PRINT.

115

SESSO=F TITOLO=1 NOME Ada -----SESSO COGNOME Mori REDDITO 40000000 -------40000000

SESSO=M TITOLO=1 NOME Mario Elia Enzo COGNOME Aloia Biorci Verdi REDDITO 32000000 27000000 35000000

SESSO=M TITOLO=2 NOME Marco Guido COGNOME Fiaschi Fusi REDDITO 26000000 35000000

SESSO=M TITOLO=4 NOME Walter -----SESSO COGNOME Chiari REDDITO 95000000 --------250000000 ========= 290000000

Figura 3.11: Tabulato risultante dell'esempio di figura 3.10 Ogni giorno vengono venduti quantitativi diversi di alcune qualit di pesce a vari prezzi. Per ogni vendita vengono appuntati i seguenti dati: tipo del pesce venduto; prezzo al Kg. ; Kg. venduti ; data di vendita. Si vuol conoscere il numero di vendite giornaliere effettuate durante un certo periodo, ed ottenere tre tabulati che mostrino il peso complessivo del pesce venduto ed il relativo importo: per ogni giorno di vendita; per tipo di pesce ; per tutto il periodo di riferimento.

116

Creiamo per prima cosa un archivio SAS che legga i dati e crei una nuova variabile di nome IMPORTO.
DATA PESCI ; INPUT PESCI $ 1-10 PREZZO 12-18 CHILI 20-28 DATA $ 30-40 ; IMPORTO = PREZZO * CHILI ; CARDS; BRANZINI 33000 276 01/01/1988 SPIGOLE 24500 98 01/01/1988 ORATE 25500 159 01/01/1988 ORATE 28000 458 02/01/1988 SPIGOLE 21000 256 02/01/1988 ORATE 31000 487 03/01/1988 BRANZINI 38500 298 03/01/1988 SPIGOLE 22000 1277 03/01/1988 RUN;

Per ottenere il riepilogo complessivo delle vendite sufficiente un passo di PROC PRINT, totalizzando le variabili IMPORTO e CHILI.
PROC PRINT; TITLE 'TOTALE GENERALE DELLE VENDITE'; ID PESCI; SUM IMPORTO CHILI; RUN;

Il risultato il seguente:
TOTALE GENERALE DELLE VENDITE PESCI BRANZINI SPIGOLE ORATE ORATE SPIGOLE ORATE BRANZINI SPIGOLE PREZZO 33000 24500 25500 28000 21000 31000 38500 22000 CHILI 276 98 159 458 256 487 298 1277 ==== 3309 DATA 01/01/1988 01/01/1988 01/01/1988 02/01/1988 02/01/1988 03/01/1988 03/01/1988 03/01/1988 IMPORTO 9108000 2401000 4054500 12824000 5376000 15097000 11473000 28094000 ======== 88427500

117

Per ottenere un prospetto che evidenzi la quantit venduta per ogni tipo di pesce ed il relativo importo, si pu scrivere il seguente programma, costituito di 2 passi di PROC.
PROC SORT DATA=PESCI; BY PESCI; PROC PRINT NOOBS; TITLE 'TOTALE VENDITE PER TIPO DI PESCE'; SUM IMPORTO CHILI ; BY PESCI; VAR PREZZO CHILI IMPORTO; RUN;

Il risultato il seguente:
TOTALE VENDITE PER TIPO DI PESCE PESCI=BRANZINI PREZZO 33000 38500 -----PESCI CHILI 276 298 --574 IMPORTO 9108000 11473000 -------20581000

PESCI=ORATE PREZZO 25500 28000 31000 -----PESCI CHILI 159 458 487 ---1104 IMPORTO 4054500 12824000 15097000 -------31975500

PESCI=SPIGOLE PREZZO 24500 21000 22000 ------PESCI CHILI 98 256 1277 ---1631 ==== 3309 IMPORTO 2401000 5376000 28094000 -------35871000 ======== 88427500

Per ottenere infine un prospetto che evidenzi la quantit venduta e l'importo fatturato giornalmente, si pu scrivere il seguente programma, costituito di 2 passi di PROC.

118

PROC SORT DATA=PESCI; BY DATA; PROC PRINT N; TITLE 'TOTALE VENDITE GIORNALIERO'; SUM IMPORTO CHILI ; BY DATA; ID DATA; VAR PESCI CHILI IMPORTO; RUN;

L'opzione N permette di conoscere il numero di vendite giornaliere. Si noti anche la forma diversa assunta dal tabulato, al variare del valore della variabile indicata nella BY. Questo tipo di uscita si ottiene specificando la stessa variabile nelle due dichiarazioni ID e BY . Il risultato che si ottiene dunque il seguente:
TOTALE VENDITE GIORNALIERO DATA 01/01/1988 PESCI BRANZINI ORATE SPIGOLE CHILI 276 159 98 ---533 IMPORTO 9108000 4054500 2401000 --------15563500

----------01/01/1988 N= 3 ORATE SPIGOLE

02/01/1988 -----------02/01/1988 N= 2

458 256 ---714

12824000 5376000 --------18200000

03/01/1988

BRANZINI ORATE SPIGOLE

----------03/01/1988

298 487 1277 ---2062 ==== 3309

11473000 15097000 28094000 --------54664000 ========= 88427500

N=

3.6.3. Cenno alla PROC QPRINT


Come risulta dai precedenti esempi, la PROC PRINT una procedura molto semplice da usare e va considerata pertanto come un ottimo strumento per ottenere con poca fatica dei tabulati "di lavoro", cio di consultazione, per controllo dati ecc.; in particolare molto utile per la sua capacit di effettuare totalizzazioni per gruppi e sottogruppi di variabili. La procedura si dimostra tuttavia 119

scarsamente flessibile se la si vuole utilizzare per produrre tabulati di una certa qualit. Il capitolo 6 di questo libro dedicato alla esposizione dei diversi metodi disponibili nel sistema SAS per produrre rapporti. Vogliamo qui tuttavia segnalare che dalla versione 5.16 del prodotto SAS stata introdotta una nuova procedura, la QPRINT, che pu essere considerata un'utile alternativa alla PRINT. Questa procedura non permette tutte le funzioni della PRINT; in particolare non esistono le dichiarazioni PAGEBY, SUM e SUMBY. Essa consente per di stampare i dati sotto forma di tabelle che possono avere pi colonne, secondo lo stile degli elenchi telefonici, con un apprezzabile risparmio del numero di pagine stampate. A titolo di esempio, un archivio SAS di 200 osservazioni ed una variabile pu essere stampato in una sola pagina contro le quattro necessarie con la PROC PRINT. Vi sono anche opzioni che permettono all'utente di poter intervenire sul formato della pagina di stampa, quali la possibilit di indicare il numero di righe bianche da lasciare fra la intestazione delle colonne ed i dati, oppure la determinazione del numero di spazi che debbono essere lasciati fra una colonna e l'altra, ecc. Per quanto concerne la velocit di esecuzione di tabulati aventi le medesime caratteristiche, la PROC QPRINT pi efficiente della PROC PRINT, se si esclude il solo caso di archivi con poche osservazioni (fino a 20) e molte variabili (oltre 100). Ad esempio per stampare un archivio di 10000 osservazioni e 10 variabili non numeriche lunghe 8, la PROC QPRINT impiega meno di met tempo di quanto impiegherebbe la PROC PRINT.

120

4. Ulteriori elementi del passo di DATA

4.1.

La gestione delle date e dei tempi

L'idea che sta alla base della gestione delle date e dei tempi nel sistema SAS, diventata di fatto uno standard e, a distanza di molti anni dalla sua prima realizzazione, stata ripresa da molti pacchetti software funzionanti sia su mainframe che su personal computer. La gestione delle date e dei tempi ha sempre causato nei linguaggi tradizionali, quali PL/I e COBOL, una serie di complicazioni. Infatti date e tempi sono usualmente visualizzati come stringhe di caratteri (es. "12/08/1947", "12-08-1947", "12 Agosto 1947", ecc.), ma sono quasi sempre rappresentati internamente come numeri (la data precedente diventerebbe il numero 12081947), sia perch cos necessitano di un minore spazio di memorizzazione, sia perch spesso si debbono eseguire, con date e tempi, delle operazioni aritmetiche, come ad esempio calcolare il numero di giorni o di settimane che intercorrono fra due date. In questi casi, prima di qualsiasi elaborazione, si deve effettuare una conversione delle date in unit omogenee, tipicamente giorni, ricordandosi di tener conto di una serie di fattori quali il computo degli anni bisestili, il diverso numero di giorni di ogni mese, ecc. Un altro problema molto comune si riscontra nel caso si debba fare un ordinamento di un archivio in funzione di una data. Infatti se questa fosse memorizzata nella forma nella quale usualmente siamo abituati a vederla, cio giorno-mese-anno, si avrebbe che il 1 Gennaio di un determinato anno sarebbe considerato dall'elaboratore "pi piccolo" del 31 Dicembre dell'anno precedente e l'archivio ordinato secondo questo criterio sarebbe ordinato impropriamente. Questo problema viene risolto con un artificio molto semplice: si memorizzano le date nella forma anno-mese-giorno. Cos la data 1 Gennaio 1988 (ovvero il numero 19880101) diviene "pi grande" della data 31 Dicembre 1987 (ovvero del numero 19871231). Tuttavia questo artificio crea nei programmi codice aggiuntivo; infatti prima che ogni data venga visualizzata, bisogna ricordarsi di trasformarla nuovamente dal formato anno-mese-giorno a quello giorno-mese-anno. 121

Nel sistema SAS la gestione delle date e dei tempi straordinariamente semplice: l'artificio utilizzato quello di trasformare ogni data ed ogni tempo in un numero, secondo le seguenti regole: ogni data rappresentata dal numero di giorni che intercorrono fra quella data ed una data di partenza; nel sistema SAS stato scelto il 1 Gennaio 1960; quindi date superiori al 1 Gennaio 1960 sono rappresentate con numeri positivi, date inferiori con numeri negativi (il 1 Gennaio 1960 convertito nel numero 0); ogni tempo rappresentato dal numero di secondi che intercorrono fra quel tempo e la mezzanotte; tale numero sempre positivo e varia da 0 a 86400 (ovvero il numero di secondi in un giorno); ogni data-tempo (cio una determinata ora di un certo giorno) rappresentata dal numero di secondi che intercorrono fra quella data-tempo e la mezzanotte del 1 Gennaio 1960; quindi date-tempi superiori alla mezzanotte del 1 Gennaio 1960 sono rappresentate con numeri positivi, date-tempi inferiori con numeri negativi. Cos il giorno 31/12/1982 rappresentato internamente dal numero 8400 (numero di giorni trascorsi dal 1/1/1960), le ore 10 di un qualsiasi giorno col numero 36000 (numero di secondi dalla mezzanotte) e le ore 10 di un certo giorno, ad esempio del 31/12/1982, sono rappresentate internamente dal numero 725796000 (numero di secondi dalla mezzanotte del 1/1/1960). A parte la curiosit, che non siamo in grado di appagare, del perch sia stata scelta come data di riferimento proprio il 1/1/1960, risulta evidente che qualunque altra data sarebbe andata comunque bene. Quando una variabile numerica che rappresenta una data o un tempo deve essere visualizzata in uscita, si dovr ordinare al sistema SAS di effettuare la conversione da rappresentazione interna a formato leggibile (esempio "giorno/mese/anno" per una data oppure "ore:minuti:secondi" per un tempo, ecc.), associando alla variabile un formato di scrittura. Quando invece si desidera creare una variabile numerica che contenga la rappresentazione interna di una data, di un tempo, o infine di una data-tempo, secondo le regole prima indicate, si deve avvertire il sistema SAS in uno dei seguenti tre modi: 1) Leggendo date e tempi con opportuni formati Se in un archivio di dati grezzi presente una stringa di caratteri che rappresenta un tempo o una data che si vuole convertire in una variabile numerica secondo le regole prima esposte, si deve leggere 122

quella data o quel tempo con uno dei formati di lettura che il sistema SAS mette a disposizione; cos se una data nella forma giornomese-anno si dovr scegliere un preciso formato in grado di interpretare correttamente la stringa da leggere. Descriviamo di seguito solo alcuni dei formati pi comuni. Tutti i formati che vedremo possono essere usati sia per leggere date e tempi, sia per visualizzarli. Esistono tuttavia formati il cui utilizzo ammesso solamente per leggere date e tempi (ad esempio SMFSTAMPc. che permette di leggere record SMF generati dal sistema operativo IBM OS/MVS) mentre altri possono essere usati solamente in fase di scrittura (ad esempio il formato WORDATEc. che permette di scrivere una data con il mese scritto con il nome inglese per esteso). Per quanto riguarda la lettura delle date, segnaliamo i seguenti tre formati: DDMMYYc. Si usa questo formato se la data nella forma "ggmmaa" dove gg il giorno, mm il mese e aa l'anno. Giorno, mese ed anno possono essere separati da spazi o caratteri speciali. L'anno pu essere composto al massimo di due cifre; "c" rappresenta il massimo numero di posizioni (o caratteri) occupati dalla data. Cos ad esempio il seguente programma:
DATA ESDATE; INPUT GIORNO DDMMYY8.; CARDS;

010186 01 1 86 1 1 86 1 01 86 01/01/86 01-01-86 01 01 86 RUN;

in grado di leggere correttamente tutte le date specificate e di trasformarle nel numero 9497 che la rappresentazione interna SAS del 1 Gennaio 1986. MMDDYYc. Questo formato legge date nella forma "mmggaa" dove mm il mese, gg il giorno e aa l'anno. Valgono le stesse considerazioni fatte per il precedente formato. YYMMDDc. Questo formato va usato se la data nella forma "aammgg" dove aa l'anno, mm il mese e gg il giorno. Valgono le stesse considerazioni fatte precedentemente con l'estensione che questo formato accetta anche l'anno di 4 cifre. Ad esempio 19860101 una data valida che pu essere letta con il formato YYMMDD8. 123

Per quanto riguarda la lettura dei tempi, segnaliamo il seguente formato: TIMEc.d Questo formato legge valori di tempo nella forma "hh:mm:ss.cc" dove hh rappresentano le ore, mm i minuti, ss i secondi e cc i centesimi di secondo. Se i secondi non vengono specificati, il sistema SAS assume il valore di 0 secondi. I caratteri ":" (due punti) sono obbligatori essendo usati come separatori. Ad esempio per leggere le ore 12, in modo che il sistema SAS esegua la trasformazione in numero di secondi a partire dalla mezzanotte (corrispondente al numero 43200), si pu codificare tale ora in uno dei seguenti modi: 12:00 oppure 12:00:00 oppure 12:00:00.0 e si deve usare rispettivamente il formato TIME5., oppure TIME8., oppure TIME10. Se infine si vuole trasformare in rappresentazione interna SAS una determinata ora di una certa data, si deve usare il seguente formato: DATETIMEc. Questo formato legge valori di data-tempo codificati nella seguente forma "ggmmmaaxhh:mm:ss.cc" o "ggmmmaaaaxhh:mm:ss.cc", dove: gg il giorno; mmm sono le prime tre lettere del mese in inglese; aa o aaaa l'anno rispettivamente di due o quattro cifre; x un carattere speciale o uno spazio; hh:mm:ss.cc sono usualmente ore, minuti, secondi e centesimi. Cos ad esempio vediamo due, fra molti possibili modi, in cui possibile specificare le ore 12 del 1 Gennaio 1986: 01JAN1986:12:00:00 (che va letto con il formato DATETIME18.) oppure 01JAN86/12:00 (che va letto con il formato DATETIME13.). 2) Utilizzando delle costanti di data, tempo e data-tempo Esistono nel sistema SAS, oltre alle consuete costanti numeriche e non numeriche, altri tre tipi di costanti: Costanti data che debbono essere codificate nella seguente forma: 'ggmmmaa'D oppure 'ggmmmaaaa'D, dove: gg il giorno composto da una o due cifre; mmm sono le prime tre lettere del mese in inglese; aa l'anno composto solo di due cifre; 124

aaaa

l'anno composto di quattro cifre.

Ad esempio '02AUG60'D, '2AUG60'D oppure '02AUG1960'D sono tutte costanti valide che sono direttamente convertite nel numero 214 (numero di giorni dal 1 Gennaio 1960). Costanti tempo che debbono essere codificate nella seguente forma: 'hh:mm:ss.cc'T, dove: hh rappresentano le ore; mm rappresentano i minuti ; ss rappresentano i secondi (opzionale); cc rappresentano i centesimi (opzionale). Ad esempio '12:30:00'T, '12:30'T , '12:30:00.0'T sono tutte costanti di tempo valide che vengono direttamente convertite nel numero 45000 (numero di secondi a partire dalla mezzanotte). Costanti data-tempo che debbono essere codificate nella seguente forma: 'ggmmmaa:hh:mm:ss.cc'DT, dove: gg il giorno; mmm sono le prime tre lettere del mese in inglese; aa l'anno composto solo di due cifre; hh rappresentano le ore; mm rappresentano i minuti ; ss rappresentano i secondi (opzionale); cc rappresentano i centesimi (opzionale). Ad esempio '02AUG60:12:30:00'DT una costante data-tempo direttamente convertita nel numero 18534600 (numero di secondi che intercorrono dalla mezzanotte del 1 Gennaio 1960). 3) Utilizzando funzioni SAS di conversione Certe volte necessario leggere date per le quali non esiste uno specifico formato SAS, quali ad esempio quelle specificate in forma giuliana (aaggg) o in formato packed. In particolare quest'ultimo caso si presenta molto spesso quando si debbono leggere archivi non SAS memorizzati su supporti magnetici, quali nastri e dischi, creati da procedure scritte in linguaggi di tipo tradizionale, come ad esempio COBOL o PL/I. In questi casi si deve fare un pizzico di lavoro aggiuntivo, e si debbono utilizzare alcune funzioni di trasformazione fornite dal sistema SAS. Alcune delle pi usate sono la funzione DATEJUL, che converte una data da for- ma giuliana in formato SAS, e le funzioni INPUT e PUT, che si rendono necessarie quando si debbono effettuare altri tipi di conversioni (vanno usate ad esempio 125

per convertire in rappresentazione SAS date packed). L'utilizzo di queste due ultime funzioni verr visto in dettaglio nel paragrafo 4.5 . Vediamo di applicare quanto detto per risolvere il seguente problema: una biblioteca vuol stampare un tabulato di tutti i libri restituiti in ritardo nel corso del 1988, tenendo presente che ogni libro deve essere restituito entro 30 giorni dalla data di prelievo. I dati a disposizione per ogni libro sono il codice, la data in cui il libro stato consegnato dalla biblioteca al richiedente e quella in cui stato restituito. Il passo di DATA che segue si compone di tre sole istruzioni. La INPUT legge la data di consegna e quella di restituzione di un determinato libro sotto forma di stringhe di caratteri, e crea rispettivamente le variabili PRESTITO e RITORNO (che vengono rappresentate internamente dal numero di giorni che intercorrono fra queste date ed il 1 Gennaio 1960). La variabile RITARDO contiene il numero di giorni di trattenimento del libro. La terza dichiarazione una IF subsetting che pone 2 condizioni legate dall'operatore logico AND; solo se entrambe sono verificate l'osservazione corrente viene scritta sul file SAS di uscita RITARDI. Si noti infine che la data di restituzione stata codificata in quattro modi diversi, tutti validi.
DATA RITARDI; INPUT CODLIBRO PRESTITO DDMMYY6. +1 RITORNO YYMMDD8.; RITARDO = RITORNO - PRESTITO ; IF RITORNO > '31DEC1987'D & RITARDO > 30 ; CARDS; 1000 270887 87 12 30 1100 301187 88-01-05 1200 250787 88/01/10 1300 271287 19880115 PROC PRINT NOOBS SPLIT = '#'; TITLE 'ESEMPIO DI SCRITTURA DI DATE NON FORMATTATE'; LABEL CODLIBRO = 'CODICE#LIBRO'; LABEL PRESTITO = 'DATA DI#PRESTITO'; LABEL RITORNO = 'DATA DI#RESTITUZIONE'; LABEL RITARDO = 'GIORNI DI#RITARDO'; RUN;

Il risultato della PROC PRINT il seguente:


ESEMPIO DI SCRITTURA DI DATE NON FORMATTATE CODICE DATA DI LIBRO PRESTITO 1100 1200 10195 10067 DATA DI GIORNI DI RESTITUZIONE RITARDO 10231 10236 36 169

Non si pu certo dire che la stampa sia un esempio di chiarezza! In effetti ci siamo dimenticati di richiedere al sistema SAS che le variabili numeriche PRESTITO e RITORNO, contenenti date in rappresentazione interna SAS, debbono essere rese leggibili prima di essere visualizzate, facendo uso di uno dei formati di uscita 126

consentiti, in grado di effettuare la conversione desiderata. Proviamo quindi a riscrivere il passo di PROC aggiungendo la dichiarazione FORMAT.
PROC PRINT NOOBS SPLIT = '#'; FORMAT PRESTITO RITORNO DDMMYY8. ; TITLE 'ESEMPIO DI SCRITTURA DI DATE FORMATTATE'; LABEL CODLIBRO = 'CODICE#LIBRO'; LABEL PRESTITO = 'DATA DI#PRESTITO'; LABEL RITORNO = 'DATA DI#RESTITUZIONE'; LABEL RITARDO = 'GIORNI DI#RITARDO'; RUN;

Il risultato della PROC PRINT ora il seguente:


ESEMPIO DI SCRITTURA DI DATE FORMATTATE CODICE DATA DI LIBRO PRESTITO 1100 1200 30/11/87 25/07/87 DATA DI GIORNI DI RESTITUZIONE RITARDO 05/01/88 10/01/88 36 169

Come si pu vedere il formato con cui le date sono stampate, pu essere anche diverso da quello con cui erano state lette. Come regola generale bisogna sempre ricordarsi di fornire un opportuno formato di uscita prima di visualizzare una data se la vogliamo scritta in modo comprensibile. Il sistema SAS mette a disposizione molte funzioni specializzate per la gestione delle date e dei tempi. In particolare segnaliamo le funzioni TODAY ( ) o DATE ( ), che ritornano la data corrente, e la funzione TIME ( ), che ritorna l'ora corrente; tutte le precedenti funzioni prelevano i dati dal sistema operativo ospite, trasformandoli in rappresentazione interna SAS (rispettivamente numero di giorni o di secondi). Vediamo ora un programma in cui vengono mostrate alcune delle funzioni pi importanti; si supponga che questo programma sia stato eseguito il giorno 24 Febbraio 1987 alle ore 18. Si noti che nell'esempio i nomi delle funzioni sono stati evidenziati per meglio distinguerli dalle variabili; si tenga presente inoltre che le variabili DATANOF ed ORANOF servono solamente per far vedere la rappresentazione interna adottata dal sistema SAS. Ricordiamo che la funzione WEEKDAY, che estrae il giorno della settimana, pu assumere valori da 1 a 7 in corrispondenza dei giorni da Domenica a Sabato. Quindi il valore 3 assunto nell'esempio dalla variabile GSETT, sta ad indicare che il 24 Febbraio 1987 era un Marted.

127

DATA DATEORE; DATA = TODAY( ) ; ORA = TIME ( ) ; DATANOF = DATA; ORANOF = ORA; ANNO = YEAR(DATA); TRIM = QTR(DATA); MESE = MONTH(DATA); GSETT = WEEKDAY(DATA); GMESE = DAY(DATA); ORE = HOUR(ORA); MINUTI = MINUTE(ORA); FORMAT DATA DDMMYY8. ORA TIME8.; PROC PRINT NOOBS; RUN;

Il risultato della PROC PRINT il seguente:


DATA 24/02/87 GSETT 3 ORA 18:00:00 GMESE 24 DATANOF 9916 ORE 18 ORANOF 64800 ANNO 1987 TRIM 1 MESE 2

MINUTI 0

4.2. Le funzioni per la manipolazione di stringhe di caratteri


Il termine "stringa" utilizzato in questo paragrafo per indicare un qualunque insieme di caratteri (lettere, cifre numeriche e/o caratteri speciali). A seconda dei casi una stringa pu essere espressa come una costante non numerica, oppure come contenuto di una variabile non numerica, oppure come risultato di una espressione non numerica. Per "manipolazione di stringhe" si intendono tutte quelle operazioni che permettono di poter estrarre da una stringa un sottoinsieme di caratteri, di poter cancatenare stringhe fra di loro, di poter effettuare una scansione di una stringa alla ricerca di uno o pi caratteri campione, oppure per determinarne la lunghezza, ecc. Il sistema SAS garantisce una grande flessibilit nella gestione delle stringhe, mettendo a disposizione una serie di strumenti quali un operatore di concatenazione ( | | ), funzioni specializzate (cfr. anche il paragrafo 2.8). Per illustrare le principali caratteristiche di questa categoria di funzioni disponibili nel sistema SAS, esaminiamo il seguente esempio. Una casa editrice sta compiendo una campagna pubblicitaria per lanciare una nuova rivista di moda; a tal scopo vuole inviare una copia omaggio a tutte le potenziali acquirenti residenti nelle regioni Toscana ed Emilia-Romagna. Gli indirizzi ove inviare la copia omaggio vanno ricostruiti, partendo da un archivio su cui sono

128

memorizzati i dati relativi a tutti gli abbonati ad altre riviste. La tabella seguente mostra il tracciato dell'archivio ed alcuni dati: Col. 1 - 5 Col. 6 - 11 Col. 12 - 15 Col. 16 - 36 Col. 37 - 46 Col. 47 - 51 Nome abbonato Cognome abbonato Codice abbonato; l'ultima lettera (F o M) identifica il sesso Via e localit separati da una virgola N telefonico e prefisso separati da un trattino Codice di avviamento postale.
111122222222223333333 678901234567890123456 3334444444 7890123456 44455 78901

12345

11 1111 678901 2345

EMY BOLLA A37F VIA FILLUNGO 2,LUCCA 22987-0583 55100 LELLA RIPOLI B5F CORSO ROMA 8,FIRENZE 325562-055 50100 ELIO LUPI AM3M VIA AURELIA 127,PISA 67054-050 56100 IVA MORI FFF P.ZA DANTE 66,MILANO 2286-02 20100 LUIGI CORTI Z4M VICOLO CORTO 44,PARMA 77901-0521 43100 LIA VERRI F LARGO AUGUSTO 2,ROMA 5497615-06 00100 .............................................................

Si deve tener presente che le regioni Toscana ed Emilia-Romagna sono riconoscibili dalle cifre "05" con cui iniziano tutti i prefissi telefonici dei diversi comuni. Si vuole creare un archivio SAS contenente tante osservazioni quante sono le potenziali acquirenti, e le seguenti variabili: SIGNORA RECAPITO CITTA nella forma "Sig.ra" Nome e Cognome separati da spazi; contenente la via ed il numero civico; contenente il CAP e la localit separati da uno spazio.

Creiamo per prima cosa un archivio SAS di nome ABBONATI contenente tutti gli abbonati alle varie riviste; i dati sono letti da un archivio non SAS identificato da TUTTI. Di seguito viene mostrato il relativo passo di DATA.
DATA ABBONATI; INFILE TUTTI; INPUT NOME $ 1-5 COGNOME $ 6-11 CODICE $ 12-15 VIA $ 16-36 TELEFONO $ 37-46 CAP $ 47-51; RUN;

Vogliamo estrarre per prima cosa il prefisso telefonico; verranno utilizzate le funzioni INDEX e SUBSTR.

129

4.2.1. Le funzioni INDEX e SUBSTR


La funzione INDEX ricerca all'interno del primo argomento la stringa specificata nel secondo argomento. In questa funzione, cos come nelle altre che vedremo, le stringhe che compaiono come argomenti, possono essere costanti non numeriche, il contenuto di variabili non numeriche o risultati di espressioni non numeriche. La sintassi della funzione la seguente: INDEX (argomento1, argomento2 ) ; dove: argomento1 una stringa in cui deve essere effettuata la ricerca; argomento2 una stringa il cui valore deve essere ricercato dentro argomento1 . La scansione di argomento1 avviene da sinistra a destra e si esaurisce: dopo aver trovato per la prima volta la stringa specificata in argomento2; al termine di argomento1 se la stringa non viene trovata. La funzione INDEX ritorna sempre come risultato della ricerca un numero. Se la ricerca ha avuto esito positivo tale numero la posizione del primo carattere della stringa specificata in argomento2; se la ricerca ha avuto esito negativo la funzione ritorna come valore 0. Consideriamo ad esempio il seguente frammento di passo di DATA:
...... A='VIA TURATI N. 27 VIAREGGIO'; RIS=INDEX(A,'VIA'); /* =====> RIS=INDEX(A,' VIA'); /* =====> RIS=INDEX(A,'via'); /* =====> ......

RIS= 1 RIS=17 RIS= 0

*/ */ */

La funzione SUBSTR usata principalmente per estrarre da una stringa una sottostringa lunga n caratteri a partire da una posizione specificata. La sintassi della funzione la seguente : SUBSTR (argomento, posizione [,n] ) ; dove: argomento una qualunque stringa; posizione 130

la posizione di partenza dalla quale comincia l'estrazione; n specifica il numero di caratteri da estrarre. Se questo dato non viene fornito, la sottostringa coincide con il resto di argomento a partire dal carattere specificato in posizione. Consideriamo ad esempio il seguente frammento di passo di DATA:
...... MACCHIN A='FIAT127' ; MARCA=SUBSTR(MACCHINA,1,4); MODELLO=SUBSTR('FIAT127',5); ......

/* ===> MARCA ='FIAT' */ /* ===> MODELLO ='127' */

Le lunghezze delle variabili MARCA e MODELLO, se non precedentemente definite, risultano essere uguali alla lunghezza dell'argomento, cio 7. Esiste anche un altro uso della funzione SUBSTR quando essa si trova a sinistra del segno = in una operazione di assegnazione: SUBSTR(argomento, posizione,n) = stringa ; In questo caso il valore di stringa posta nella variabile specificata in argomento a partire da posizione e sostituisce il numero di caratteri specificato da n. Non possibile specificare in argomento una costante. Ad esempio dopo il seguente frammento di passo di DATA:
...... MACCHINA = 'FIAT127'; SUBSTR(MACCHINA,5,3) ='5' || '00'; ......

la variabile MACCHINA contiene la stringa 'FIAT500' . Tornando all'esercizio, scriviamo la prima parte del passo di DATA che permette l'estrazione del prefisso dal numero telefonico. I dati vengono prelevati dall'archivio SAS ABBONATI, creato precedentemente.
DATA OMAGGI ; SET ABBONATI; /* ESTRAE IL PREFISSO DAL NUMERO TELEFONICO */ POS=INDEX(TELEFONO,'-') ; IF POS > 0 THEN PREFISSO=SUBSTR(TELEFONO,POS+1); IF SUBSTR(PREFISSO,1,2) = '05' ; .......

La variabile POS contiene la posizione del trattino che divide il numero telefonico dal prefisso (6 per la prima osservazione, 7 per la seconda, ecc.). La variabile PREFISSO contiene il prefisso 131

telefonico, cio la sottostringa della variabile TELEFONO a partire da POS+1 fino al termine. Infine la dichiarazione IF subsetting fa filtrare le sole osservazioni nelle quali i primi due caratteri della variabile PREFISSO sono '05'. La definizione della variabile POS non indispensabile; poich infatti un argomento di una funzione pu essere a sua volta un'altra funzione, le due dichiarazioni in cui POS compare potrebbero essere sostituite dalla seguente:
IF INDEX(TELEFONO,'-') > 0 THEN PREFISSO=SUBSTR(TELEFONO,(INDEX(TELEFONO,'-')+1));

Determiniamo ora se l'abbonato un maschio o una femmina; per far questo bisogna introdurre anche la funzione LENGTH.

4.2.2. La funzione LENGTH


La funzione fornisce la lunghezza della espressione specificata nell'argomento. La sintassi della funzione LENGTH la seguente : LENGTH (argomento) dove: argomento una qualunque stringa. Per calcolare la lunghezza, la funzione scandisce, da destra verso sinistra, la stringa specificata in argomento; il valore che la funzione ritorna la posizione del carattere diverso da spazio posto pi a destra. Se la stringa specificata nell'argomento costituita solamente da spazi, LENGTH ritorna come valore 1. Consideriamo ad esempio il seguente frammento di passo di DATA:
...... VARC='CASA MIA '; N=LENGTH(VARC); ......

/* N = 8 */

Tornando all'esercizio, aggiungiamo la parte di programma che determina il sesso dell'abbonato. La funzione LENGTH necessaria in quanto la variabile CODICE, da cui si deve estrarre l'ultimo carattere, ha lunghezza variabile. La funzione LENGTH(CODICE), che nella prima osservazione ritorna il valore 4, nella seconda 3, ecc., lo strumento idoneo per indicare alla funzione SUBSTR dove localizzato l'ultimo carattere contenente il sesso dell'abbonato. In assenza della dichiarazione LENGTH (da non confondersi con la funzione LENGTH), la variabile SESSO sarebbe lunga 4 posizioni. 132

DATA

OMAGGI; SET ABBONATI; /* ESTRAE IL PREFISSO DAL NUMERO TELEFONICO */ POS=INDEX(TELEFONO,'-') ; IF POS > 0 THEN PREFISSO=SUBSTR(TELEFONO,POS+1); IF SUBSTR(PREFISSO,1,2) = '05' ; /* DETERMINA IL SESSO DELL'ABBONATO */ LENGTH SESSO $1; SESSO=SUBSTR(CODICE,LENGTH(CODICE),1); IF SESSO = 'F' ; ......

Dobbiamo ora definire la variabile SIGNORA. E' necessario introdurre l'operatore di concatenazione ( | | ) e la funzione TRIM.

4.2.3. Loperatore di concatenazione e la funzione TRIM


L'operatore di concatenazione ( | | ) serve per congiungere delle stringhe di caratteri. La sintassi d'uso la seguente: stringa1 | | stringa2 dove: stringa1 e stringa2 sono due qualunque stringhe. Consideriamo ad esempio il seguente frammento di passo di DATA:
...... A = 'CASA '; B = 'BLANCA'; VAR = A || B; /* ......

==> VAR='CASA

BLANCA' */

La variabile VAR, se non precedentemente definita, lunga 16 posizioni essendo uguale alla lunghezza di A (10) pi la lunghezza di B (6). Come si vede l'operatore di concatenazione non elimina gli spazi alla destra della variabile A. Questa operazione viene svolta dalla funzione TRIM. TRIM (argomento) dove: argomento una qualunque stringa.

133

Se applichiamo otteniamo:

la

funzione TRIM all'esempio

precedente,

...... A = 'CASA '; B = 'BLANCA'; VAR = TRIM(A) || B;/* ===> VAR = 'CASABLANCA' */ ......

La lunghezza di VAR, se non precedentemente definita, resta uguale a 16 posizioni. L'operatore di concatenazione e la funzione TRIM vengono utilizzati nell'esercizio per costruire la variabile SIGNORA, congiungendo 4 sottostringhe, due delle quali sono costanti, e due variabili non numeriche. La funzione TRIM si rende necessaria solo per la variabile NOME in quanto vanno eliminati gli eventuali spazi alla destra di tale variabile. La costante ' ' serve per separare il nome dal cognome.
DATA OMAGGI; SET ABBONATI; /* ESTRAE IL PREFISSO DAL NUMERO TELEFONICO */ POS=INDEX(TELEFONO,'-') ; IF POS > 0 THEN PREFISSO=SUBSTR(TELEFONO,POS+1); IF SUBSTR(PREFISSO,1,2) = '05' ; /* DETERMINA IL SESSO DELL'ABBONATO */ LENGTH SESSO $1 ; SESSO=SUBSTR(CODICE,LENGTH(CODICE),1); IF SESSO = 'F' ; /* CREA LA VARIABILE SIGNORA */ SIGNORA='Sig.ra ' ||TRIM(NOME) || ' ' || COGNOME; .....

La costruzione delle ultime due variabili RECAPITO e CITTA richiede infine l'uso della funzione SCAN.

4.2.4. La funzione SCAN


La funzione estrae la n-sima parola da una stringa di caratteri. La sintassi della funzione SCAN la seguente : SCAN (argomento,n [, 'delimitatori']) dove: argomento una qualunque stringa; n specifica la n-sima parola da estrarre; 'delimitatori' 134

definiscono i caratteri che separano una parola dalla successiva. Se nessun delimitatore viene specificato, il sistema SAS assume che ciascuno dei seguenti caratteri sia un separatore di parole: spazio . < ( + | & $ * ) ; - / , % La scansione avviene da sinistra verso destra. Se vi sono due o pi delimitatori contigui, essi vengono considerati come uno solo. Se in argomento vi sono meno di n parole, la funzione d come risultato valore mancante. Delimitatori trovati a sinistra della prima parola non vengono considerati. Vediamo ad esempio il seguente frammento di passo di DATA:
...... VAR='NEL MEZZO DEL CAMMIN DI NOSTRA VITA'; SCAN1 = SCAN(VAR,4); /* ====> SCAN1 = 'CAMMIN' */ SCAN2 = SCAN(VAR,2,','); /* ====> SCAN2 = ' ' */ ......

La lunghezza delle variabili SCAN1 e SCAN2, se non precedentemente definita, di 200 posizioni nel caso dei mainframes, o uguale alla lunghezza della variabile specificata in argomento negli altri ambienti. Siamo ora finalmente in grado di terminare l'esercizio.
DATA OMAGGI; KEEP SIGNORA RECAPITO CITTA; SET ABBONATI; /* ESTRAE IL PREFISSO DAL NUMERO TELEFONICO */ POS=INDEX(TELEFONO,'-') ; IF POS > 0 THEN PREFISSO=SUBSTR(TELEFONO,POS+1); IF SUBSTR(PREFISSO,1,2) = '05' ; /* DETERMINA IL SESSO DELL'ABBONATO */ LENGTH SESSO $1 ; SESSO=SUBSTR(CODICE,LENGTH(CODICE),1); IF SESSO = 'F' ; /* CREA LA VARIABILE SIGNORA */ SIGNORA ='Sig.ra ' || TRIM(NOME) || ' ' || COGNOME; /* CREA LE VARIABILI RECAPITO E CITTA */ LENGTH RECAPITO CITTA $30 ; RECAPITO = SCAN(VIA,1,',') ; CITTA = CAP || ' ' || SCAN(VIA,2,',') ; RUN;

La funzione SCAN viene utilizzata per separare nella variabile VIA l'indirizzo dalla citt creando cos due nuove variabili RECAPITO e CITTA. Per evitare che le due variabili siano lunghe 200 posizioni ciascuna, stata inserita una dichiarazione LENGTH. E' stata infine inserita una dichiarazione KEEP per limitare il numero di variabili nell'archivio OMAGGI. Scriviamo al termine un passo di PROC, al fine di stampare i risultati della elaborazione effettuata. 135

PROC PRINT DATA=OMAGGI NOOBS; TITLE 'ELENCO ABBONATE A CUI MANDARE UN OMAGGIO'; RUN;

Questo programma SAS produce la seguente uscita:


ELENCO ABBONATE A CUI MANDARE UN OMAGGIO SIGNORA Sig.ra EMY BOLLA Sig.ra LELLA RIPOLI RECAPITO VIA FILLUNGO 2 CORSO ROMA 8 CITTA 55100 LUCCA 50100 FIRENZE

4.3.

La gestione dei valori mancanti

Abbiamo a pi riprese parlato di come il sistema SAS gestisce i valori mancanti Molte raccolte di dati includono valori mancanti: essi stanno a significare, a seconda dei casi, risposte mancanti o errate a domande di un questionario, voti non assegnati ad un compito in classe perch l'alunno era assente, valori non pervenuti in una tabella che riporta le temperature minime e massime di stazioni meteorologiche, ecc. Ma esistono altri casi in cui vengono generati valori mancanti; quando ad esempio il sistema SAS tenta di leggere variabili definite numeriche ma che contengono valori errati, oppure vengono eseguite operazioni invalide, come ad esempio la divisione per 0, nel corso di un programma. Esploreremo ora questo argomento cercando di dare una risposta ad alcune domande molto comuni, relative all'uso dei valori mancanti. Come si rappresentano in ingresso i valori mancanti ?

Quando una variabile in ingresso, numerica o non numerica, ha valore mancante, questa pu essere rappresentata da un punto o da spazi secondo le regole mostrate nella tabella di figura 4.1. Come viene evidenziato dalla tabella, per tutti i tipi di INPUT e per tutti i tipi di variabile, i valori mancanti possono essere sempre rappresentati da un punto.
TIPO DI INPUT INPUT a colonne INPUT a lista INPUT a formati Punto SI SI SI Spazi SI NO SI

Figura 4.1: Codifica di un valore mancante 136

Come si fa a leggere una variabile non numerica avente per valore un punto ?

Si deve utilizzare il formato "$CHAR.", come si pu vedere dal seguente esempio nel quale sono riportati una serie di segni di punteggiatura ed il numero di volte che compaiono in un testo.
DATA ; INPUT SIMBOLO $CHAR1. NUMERO; CARDS4; ! 1 , 15 ; 5 . 12 ;;;; PROC PRINT; TITLE 'LETTURA DEL CARATTERE ";" E USO DI CARDS4' ; RUN;

In questo particolare caso il carattere "." non vuole significare valore mancante. Si noti anche l'uso di CARDS4, in quanto uno dei simboli che compare nei dati proprio il ";" . L'uscita della PROC PRINT la seguente:
LETTURA DEL CARATTERE ";" E USO DI CARDS4 OBS 1 2 3 4 SIMBOLO ! , ; . NUMERO 1 15 5 12

Come sono rappresentati internamente i valori mancanti e come vengono visualizzati ?

Per quanto riguarda le variabili non numeriche i valori mancanti sono rappresentati internamente e visualizzati da una stringa spazi; per quanto riguarda le variabili numeriche i valori mancanti sono invece visualizzati da un punto e rappresentati internamente da un particolare numero floating (in notazione esadecimale '8000000000000000'). Come si assegna da programma un valore mancante ad una variabile?

E' sufficiente assegnare a quella variabile, numerica o non numerica, il valore "." . Si leggano ad esempio le risposte di un questionario, e 137

si voglia assegnare valore mancante alla variabile RISPOSTA tutte le volte che essa assume il valore 0 e 9. Si desidera poi eseguire una statistica che evidenzi quante risposte hanno valore mancante.
DATA TRASFORM; INPUT ID RISPOSTA ; IF RISPOSTA = 0 OR RISPOSTA = 9 THEN RISPOSTA = . ; CARDS; 1 0 2 1 3 1 4 9 5 9 PROC FREQ; TABLES RISPOSTA/MISSING; RUN;

Anche se i dettagli della PROC FREQ verranno presentati nel capitolo 7, interessante vedere l'uscita prodotta dalla procedura:
RISPOSTA . 1 FREQUENCY 3 2 PERCENT 60.0 40.0 CUMULATIVE FREQUENCY 3 5 CUMULATIVE PERCENT 60.0 100.0

-------------------------------------------------------------------------------

Come si fa ad avere classi differenziate di valori mancanti ?

Sempre nell'esempio precedente, supponiamo che il valore 0 stia a significare: "La persona si rifiutata di rispondere" mentre il valore 9 stia a significare "La persona ha risposto in modo errato". Pu essere interessante avere due classi distinte di valori mancanti e poter distinguere quindi fra questi casi. Solo per le variabili numeriche, il sistema SAS permette di creare fino a 27 classi distinte di valori mancanti. I valori con cui possibile identificare queste classi sono il simbolo " _ " (sottolineato) e le 26 lettere maiuscole dell'alfabeto inglese. Dovremo anche dichiarare al sistema SAS, per mezzo della dichiarazione MISSING, quali simboli abbiamo scelto per identificare classi di valori mancanti. Cos, nell'esempio precedente, scegliamo le lettere A e B, in quanto esistono solamente due categorie diverse di valori mancanti. Vediamo come si trasforma il precedente programma SAS.

138

DATA TRASFORM; INPUT ID RISPOSTA ; MISSING A B; IF RISPOSTA = 0 THEN RISPOSTA = 'A'; IF RISPOSTA = 9 THEN RISPOSTA = 'B'; CARDS; 1 0 2 1 3 1 4 9 5 9 PROC FREQ; TABLES RISPOSTA/MISSING; RUN;

L'uscita della PROC FREQ stavolta sar la seguente:


CUMULATIVE FREQUENCY 1 3 5 CUMULATIVE PERCENT 20.0 60.0 100.0

RISPOSTA A B 1

FREQUENCY 1 2 2

PERCENT 20.0 40.0 40.0

-------------------------------------------------------------------------------

Come si fa a sapere se una variabile contiene valore mancante ?

Se la variabile da esaminare numerica, essa va confrontata con un punto, se la variabile non numerica sono possibili diversi tipi di confronto. Ad esempio in figura 4.2 sono mostrate una serie di dichiarazioni IF tendenti a conoscere se la variabile numerica QUEST e/o la variabile non numerica RISPOSTA contengono valore mancante. Come si vede, se il contenuto della variabile RISPOSTA fosse valore mancante, tutte le dichiarazioni IF escluso l'ultima, eseguirebbero la dichiarazione specificata dopo THEN.
DATA _NULL_ ; INPUT QUEST RISPOSTA $ IF QUEST = . THEN IF RISPOSTA = '' THEN IF RISPOSTA = . THEN IF RISPOSTA = ' ' THEN IF RISPOSTA = '.' THEN ...............

; ... ... ... ... ...

; ; ; ; ;

/* /* /* /* /*

test valido test valido test valido test valido test invalido

*/ */ */ */ */

Figura 4.2: Modi diversi per vedere se il valore di una variabile mancante

139

Come si comportano i valori mancanti con gli operatori di confronto ?

Nel contesto di una dichiarazione IF il confronto con valore mancante equivale, per le variabili numeriche, al confronto con il pi piccolo valore numerico possibile. Per le variabili non numeriche, il valore mancante una stringa contenente spazi e, come tale, risulta "pi piccola" di qualunque altra stringa. Ad esempio nel seguente frammento di programma, se il contenuto della variabile NUMERO fosse valore mancante, tutte le istruzioni IF eseguirebbero la dichiarazione specificata dopo THEN.
.............. IF NUMERO < 1000 IF NUMERO < 0 IF NUMERO < -1000 .............. THEN ... ; THEN ... ; THEN ... ;

Come comportarsi in un passo di DATA quando alcune variabili possono assumere valore mancante ?

Si pu rispondere in un solo modo: con molta cautela. E' consigliabile fare uso delle funzioni, che, come si visto a proposito delle totalizzazioni, risolvono il problema dei valori mancanti ignorandoli. Consideriamo il seguente esempio:
DATA; INPUT NUMERO1 NUMERO2 NUMERO3; TOT1 = NUMERO1 + NUMERO2 + NUMERO3; TOT2 = SUM(NUMERO1,NUMERO2,NUMERO3); MEDIA1=(NUMERO1+NUMERO2+NUMERO3)/3; MEDIA2=MEAN(NUMERO1,NUMERO2,NUMERO3); CARDS; 10 20 30 40 . 60 PROC PRINT NOOBS; TITLE 'LE FUNZIONI ED I VALORI MANCANTI'; RUN;

Il risultato della PROC PRINT fornisce il seguente tabulato:


LE FUNZIONI ED I VALORI MANCANTI NUMERO1 NUMERO2 NUMERO3 TOT1 TOT2 MEDIA1 MEDIA2 10 40 20 . 30 60 60 . 60 100 20 . 20 50

4.4.

Altre dichiarazioni del passo di DATA

140

Verranno qui esaminate alcune dichiarazioni la cui conoscenza non indispensabile per i primi programmi che un utente si accinge a scrivere, ma che vengono ugualmente trattate per un duplice motivo: esse infatti permettono di scrivere in modo semplice alcune applicazioni che altrimenti richiederebbero un numero molto maggiore di istruzioni ed inoltre tutte le dichiarazioni che vedremo sono presenti, in forme sintattiche pi o meno analoghe, nella maggior parte dei linguaggi pi diffusi. Per questo motivo verranno fatti dei riferimenti ad altri linguaggi, che possono essere del tutto ignorati da coloro che tali linguaggi non conoscono.

4.4.1. Le variabili automatiche _N_ ed _ERROR_


Prima di esaminare in dettaglio nuove dichiarazioni, necessario integrare quanto gi detto nel capitolo 2 a proposito del Program Data Vector (PDV). Come noto esso esso un'area di memoria costruita durante la fase di compilazione di un passo di DATA contenente tutte le variabili che sono definite nel passo di DATA. Oltre a queste variabili definite dall'utente, esistono nel PDV altre variabili "automatiche", cio generate dal sistema SAS, che sono utilizzabili durante il passo di DATA ma che non vengono mai riportate sugli archivi SAS di uscita. Due di queste variabili automatiche, sempre generate dal sistema SAS, sono particolarmente importanti: _N_ tale variabile numerica assume il valore di 1 la prima volta che il passo di DATA viene eseguito. Successivamente, ogni volta che il sistema SAS comincia una nuova esecuzione del passo di DATA, il valore di _N_ viene incrementato di 1. Al termine del passo di DATA, _N_ conterr un valore che indica quante volte il passo di DATA stato eseguito. tale variabile numerica pu assumere due valori, al termine di ogni esecuzione del passo di DATA: 0 se il sistema SAS non ha rilevato nessun errore di dati durante l'esecuzione dell'i-esimo ciclo del passo di DATA; 1 se il sistema SAS ha rilevato almeno un errore di dati (ad esempio una divisione per zero, un dato numerico invalido ecc.) durante l'esecuzione dell'i-esimo ciclo del passo di 141

_ERROR_

DATA. Tutte le volte che il sistema SAS ricomincia l'esecuzione di un passo di DATA, cio incrementa il valore di _N_ , il valore della variabile _ERROR_ viene reimpostato a 0. A titolo di esempio scriviamo un passo di DATA che debba leggere da un archivio di dati grezzi su disco, identificato dal nome DISCO della INFILE, un certo numero di record. Tale numero non noto a priori, ma contenuto nella variabile MAXREC di un archivio SAS permanente di nome MIEI.VALORI. Vogliamo inoltre che il programma termini nel caso venga rilevato un qualunque errore di dati nel file di ingresso.
DATA LEGGI; IF _N_ = 1 IF _N_ > MAXREC INFILE DISCO; INPUT ........ IF _ERROR_ = 1 RUN; THEN SET MIEI.VALORI; THEN STOP ; /*punta al file da leggere*/ ; /* legge i dati */ THEN STOP ;

Da notare che la dichiarazione SET viene eseguita solo una volta nel corso del programma, durante la prima esecuzione del passo di DATA; essa legge la prima osservazione dell'archivio SAS MIEI.VALORI che contiene la variabile MAXREC. Durante i passaggi successivi infatti, la condizione specificata nella IF risulta falsa, essendo il valore di _N_ > 1. La dichiarazione STOP (che fa terminare il passo di DATA), viene eseguita quando il valore di _N_ > MAXREC, (ovvero appena il numero di record letti supera il valore richiesto), o appena stato rilevato un qualsiasi errore durante la lettura del file. Non stata inserita una dichiarazione "RETAIN MAXREC" perch viene assegnato il valore a MAXREC durante una dichiarazione SET. In tal caso il sistema SAS conserva il valore della variabile nel PDV anche nei cicli successivi al primo, cio esegue una RETAIN automatica.

4.4.2. La dichiarazione RETURN


Questa dichiarazione assume significati diversi a seconda del contesto del passo di DATA in cui essa compare. Vi sono 3 situazioni possibili: Quando il sistema SAS incontra una dichiarazione RETURN, in una routine richiamata da una LINK, esso torna ad eseguire la dichiarazione che segue immediatamente la dichiarazione LINK stessa (vedere per dettagli ed esempi il paragrafo 4.4.4). 142

Durante la preparazione di un tabulato personalizzato, ottenuto con le dichiarazioni PUT e FILE, spesso si intestano le pagine utilizzando una routine, indirizzata dall'opzione HEADER nella dichiarazione FILE, richiamata in modo automatico al termine di ciascuna pagina. Quando questo accade, viene generata una LINK automatica alla etichetta specificata dopo la HEADER; l'ultima dichiarazione della routine di intestazione deve essere una RETURN. Quando il sistema SAS la incontra, torna alla dichiarazione immediatamente seguente l'ultima eseguita prima di saltare alla routine di intestazione, continuando da quel punto l'esecuzione (vedere capitolo 6 per dettagli ed esempi). In tutti gli altri casi, dopo aver eseguito una dichiarazione RETURN, il sistema SAS torna all'inizio del passo di DATA per un'altra esecuzione, incrementando di 1 il valore corrente della variabile automatica _N_ ed assegnando valore mancante a tutte le variabili del PDV per le quali non stata specificata una RETAIN (implicita o esplicita). Prima che ci accada, il contenuto del PDV viene scritto sull'archivio (o su tutti gli archivi) di uscita solo se non compaiono dichiarazioni OUTPUT nel passo di DATA. Vediamo un esempio relativo all'ultimo uso descritto della RETURN, rimandando ai capitoli e paragrafi specificati per esempi degli altri usi.
DATA POSITIVI ; INPUT NUMERO ; IF NUMERO <= 0 THEN RETURN ; CARDS; 10 -1 20 PROC PRINT; RUN;

L'uscita della PROC PRINT la seguente:


OBS 1 2 3 NUMERO 10 -1 20

Come si pu vedere, l'archivio SAS di uscita, nonostante il nome POSITIVI, contiene tre osservazioni in quanto la dichiarazione:
IF NUMERO <= 0 THEN RETURN ;

risulta inutile nel contesto; infatti, se vero che per valori negativi della variabile NUMERO viene eseguita la dichiarazione RETURN, 143

altrettanto vero che viene comunque scritta l'osservazione corrente sull'archivio di uscita, prima di tornare all'inizio del passo di DATA. Perch le cose funzionino, sufficiente modificare il precedente passo di DATA aggiungendo una dichiarazione OUTPUT.
DATA POSITIVI ; INPUT NUMERO ; IF NUMERO <= 0 THEN RETURN ; ELSE OUTPUT ; CARDS; 10 -1 20 PROC PRINT; RUN;

L'uscita della PROC PRINT ora la seguente:


OBS 1 2 NUMERO 10 20

4.4.3. Etichette e dichiarazione GO TO


Nel sistema SAS, cos come in quasi tutti gli altri linguaggi, possibile usare una etichetta per identificare dichiarazioni eseguibili a cui si vuole "saltare" durante la esecuzione di un passo di DATA, per mezzo di una dichiarazione GO TO o LINK (vedere paragrafo 4.4.4). La sintassi della dichiarazione GO TO la seguente: GO TO etichetta ; dove: etichetta identifica il punto del passo di DATA a cui saltare. Una etichetta pu essere un qualunque nome SAS valido seguito da ":" (due punti). L'unico vincolo nella scelta dei nomi che non possono esserci due etichette aventi lo stesso nome all'interno di un passo di DATA. Con linguaggi di tipo tradizionale, come ad esempio le prime versioni del FORTRAN, l'uso della dichiarazione GO TO era quasi inevitabile. L'uso eccessivo del GO TO rendeva inevitabilmente i programmi di difficile lettura, anche per l'autore. Con l'avvento dei nuovi linguaggi e delle moderne metodologie di programmazione strutturata, la dichiarazione GO TO stata bandita dai programmi; ma teoria e pratica, come noto, non marciano sempre alla stessa velocit! 144

Si debbano ad esempio creare due archivi SAS, contenenti rispettivamente numeri positivi e negativi, in funzione di dati letti da terminale. Se la variabile NUMERO assume valore uguale a zero, non va scritta su nessuno dei due archivi. Una possibile soluzione "tradizionale" la seguente:
DATA POSITIVI NEGATIVI; INPUT NUMERO ; IF NUMERO > 0 THEN GO IF NUMERO < 0 THEN GO RETURN; /* POSITIVI: OUTPUT POSITIVI; RETURN; /* NEGATIVI: OUTPUT NEGATIVI; RETURN; /* CARDS; .... dati di ingresso .... ;

TO POSITIVI; TO NEGATIVI; riesegue il passo DATA */ riesegue il passo DATA */ riesegue il passo DATA */

Lo stesso programma pu essere riscritto, in una forma pi leggibile, nel seguente modo:
DATA POSITIVI NEGATIVI; INPUT NUMERO ; IF NUMERO = 0 THEN RETURN; ELSE IF NUMERO > 0 THEN OUTPUT POSITIVI; ELSE OUTPUT NEGATIVI; CARDS; .... dati di ingresso .... ;

4.4.4. La dichiarazione LINK


Questa istruzione permette di saltare ad un punto del passo di DATA identificato dalla etichetta specificata nella dichiarazione stessa, e di continuare l'esecuzione del passo di DATA a partire da quel punto e fino a che viene incontrata una dichiarazione RETURN. Quando viene eseguita la RETURN, la esecuzione del passo di DATA riprende a partire dalla dichiarazione immediatamente seguente la LINK. Questa dichiarazione, simile alla "PERFORM" del linguaggio COBOL oppure alla "CALL" del linguaggio FORTRAN, permette di strutturare il passo di DATA in routines elementari ed particolarmente utile quando una stessa routine viene richiamata da punti diversi del programma. La sintassi della dichiarazione LINK viene mostrata di seguito. LINK etichetta ; dove: etichetta identifica il punto del passo di DATA a cui saltare. 145

E' da tener presente che all'interno di una routine possono trovarsi altre dichiarazioni LINK che, a loro volta, possono richiamare altre routines. Consideriamo in figura 4.3 un esempio di passo DATA strutturato in un segmento principale e due routines, CALC1 e CALC2; in questo programma compaiono due dichiarazioni LINK, (rispettivamente alle etichette CALC2 e CALC1) e tre dichiarazioni RETURN. Due di queste chiudono le routines CALC1 e CALC2. La terza, invece, serve per separare la parte principale del passo di DATA dalle due routines. Quando questa ultima RETURN viene eseguita, ricomincia un nuovo ciclo del passo di DATA, senza che nessuna osservazione venga scritta in modo automatico sul file SAS di uscita, in quanto presente nel programmauna dichiarazione OUTPUT.
DATA CALCOLA; DROP N; INPUT N A B ; IF N = 2 THEN LINK CALC2; ELSE LINK CALC1; IF TOTALE > 0 THEN OUTPUT; RETURN; CALC1: TOTALE = A + B ; RETURN; CALC2: TOTALE = A - B ; RETURN; CARDS; 1 2 3 2 4 3 3 4 5 PROC PRINT; TITLE 'ESEMPIO DI USO DELLA DICHIARAZIONE LINK'; RUN;

Figura 4.3: Esempio di richiamo di routines con la dichiarazione LINK Il risultato della PROC PRINT mostrato in figura 4.4:
ESEMPIO DI USO DELLA DICHIARAZIONE LINK OBS 1 2 A 2 4 B 3 3 TOTALE 5 1

Figura 4.4: Uscita dell'esempio di figura 4.3

4.4.5. La dichiarazione DO
Questa dichiarazione tipica di elaborazioni che eseguono calcoli ripetitivi, ed da sempre molto usata in linguaggi di tipo scientifico, 146

in particolare il FORTRAN e PL/I, ma esiste anche in linguaggi evoluti tipo C e PASCAL. La dichiarazione DO permette di far ripetere l'esecuzione di un gruppo di istruzioni che si trovano fra lo stesso DO ed una dichiarazione END, un determinato numero di volte o fino al verificarsi di una condizione. Tutte le dichiarazioni comprese fra il DO e la END prendono il nome di "corpo del DO" mentre la dichiarazione END, che deve essere sempre specificata, segnala la fine dl ciclo del DO. Il sistema SAS mette a disposizione diversi tipi di DO; esamineremo nel seguito i principali. La sintassi pi semplice della dichiarazione DO, la seguente: DO ; ........ istruzioni SAS ............. END ; dove: indice il nome di una qualunque variabile SAS che controlla il ciclo del DO. Essa viene aggiunta nel PDV e riportata nell'archivio SAS di uscita, a meno che non sia esclusa con una dichiarazione DROP. inizio, fine possono essere espressioni, costanti o variabili numeriche o non numeriche, che controllano il numero di volte che il ciclo del DO deve essere ripetuto. I loro valori sono calcolati prima che il ciclo del DO venga eseguito la prima volta, e questi valori non possono pi essere modificati all'interno del DO. La prima volta che il ciclo del DO viene eseguito, ad indice viene assegnato il valore di inizio. L'esecuzione continua fino a che indice risulta maggiore di fine, se l'incremento specificato positivo, o fino a che indice risulta minore di fine, se l'incremento specificato negativo. incremento un qualunque numero o una espressione il cui risultato viene, ad ogni ciclo del DO, sommato (se positivo) o sottratto (se negativo) al valore corrente di indice . Se incremento non specificato, il sistema SAS assume un valore di 1. Esempi: DO I=1 TO 10 ; il DO viene eseguito 10 volte. Al termine del DO I vale 11. 147 indice = inizio [TO fine [BY incremento ] ] [, inizio [TO fine [BY incremento ] ] ] .....

DO I=1 TO 10 BY 1; stesso funzionamento del DO precedente. DO K=10 TO 1 BY -2 ; il DO viene eseguito 5 volte. Al termine del DO K vale 0. DO J=.1 TO 1.0 BY .3; il DO viene eseguito 4 volte. Al termine del DO J vale 1.3 . DO DATA='01JAN88'D TO '10JAN88'D BY 30; Dopo che le costanti data sono state convertite in numero di giorni, il sistema SAS trasforma il DO specificato nel seguente modo: DO DATA=10227 TO 10236 BY 30 e lo esegue una sola volta. Vediamo ora alcuni esempi di casi particolari: N=3; DO INDICE=N TO 2 BY 1; Il DO non viene mai eseguito. DO INDICE=100 ; Il DO viene eseguito solo una volta. DO INDICE=1, 5, 10, 50, 100 ; Il DO viene eseguito 5 volte attribuendo alla variabile INDICE i valori indicati. DO GIORNO='DOMENICA', 'LUNEDI' ; Il DO viene eseguito 2 volte. La variabile GIORNO usata come indice non numerica. DO I=1 TO 10 BY 1, 10 TO 1 BY -1; Il DO composto da due cicli diversi; in totale eseguito 20 volte. Due altri tipi di DO molto usati sono il DO WHILE ed il DO UNTIL, che hanno la seguente sintassi: DO WHILE (espressione ) ; ...... istruzioni SAS ...... END ; dove: espressione una qualunque espressione SAS valida. Questo tipo di DO pu essere cos tradotto: esci dal ciclo di DO quando l'espressione non pi verificata. Il controllo di veridicit della espressione viene effettuato all'inizio del ciclo di DO.

148

DO UNTIL (espressione ) ; ..... istruzioni SAS ...... END ; dove: espressione una qualunque espressione SAS valida. Questo tipo di DO pu essere cos tradotto: esci dal ciclo di DO quando l'espressione verificata. Il controllo di veridicit della espressione viene effettuato al termine del ciclo di DO. Ci significa che il ciclo di DO viene sempre eseguito almeno una volta. Come esempio supponiamo di avere un capitale di 20 milioni, che vogliamo investire a partire dal 1 Gennaio 1986 ad un tasso annuo del 10%. Vogliamo sapere dopo quanti anni il capitale supera i 50 milioni. Le dichiarazioni DO UNTIL e DO WHILE mostrate nell'esempio, sono perfettamente interscambiabili.
DATA RENDITA; CAPITALE = ANNO=1985; DO WHILE ( /* o DO UNTIL ( CAPITALE + ANNO+1; END; PROC PRINT NOOBS; RUN; 20000000; CAPITALE <= 50000000 ); CAPITALE > 50000000 ); */ (CAPITALE * 0.10);

Figura 4.5: Esempio di uso del DO WHILE e/o DO UNTIL I vari tipi di DO visti possono anche essere combinati in una unica dichiarazione, come si pu vedere dal programma che segue il cui funzionamento identico a quello di figura 4.5. In tal caso il DO termina non appena si verifica che ANNO diventa maggiore di 1999 oppure CAPITALE diventa maggiore di 50 milioni.
DATA RENDITA; CAPITALE = 20000000; DO ANNO=1985 TO 1999 WHILE (CAPITALE <= 50000000); CAPITALE + (CAPITALE * 0.10); END; PROC PRINT NOOBS; RUN;

L'uscita della PROC PRINT di entrambi gli esempi precedenti mostrata in figura 4.6 ed evidenzia il capitale maturato alla fine del 1995.
CAPITALE 51874849 ANNO 1995

Figura 4.6: Uscita dell'esempio di figura 4.5 149

All'interno di un DO possono comparire altri DO senza alcuna limitazione ("nidi di DO"). Supponiamo che nell'esempio di figura 4.5 si voglia conoscere dopo quanti anni e mesi il capitale iniziale supera i 50 milioni, supponendo che gli interessi maturati ogni mese, vengano subito reinvestiti. Il passo di DATA potrebbe essere cos modificato:
DATA RENDITA; CAPITALE = 20000000; DO ANNO = 1985 TO 1999 WHILE ( CAPITALE <= 50000000 ); DO MESE = 0 TO 11 WHILE (CAPITALE <= 50000000); CAPITALE + (CAPITALE * 0.10/12); END; END; PROC PRINT NOOBS; VAR CAPITALE ANNO MESE; TITLE 'ESEMPIO DI NIDI DI DO'; RUN;

L'uscita della PROC PRINT evidenzia che il traguardo dei 50 milioni viene superato al termine del mese di marzo del 1995.
ESEMPIO DI NIDI DI DO CAPITALE 50244414 ANNO 1995 MESE 3

4.4.6. La dichiarazione ARRAY


La dichiarazione ARRAY ha subito molte trasformazioni di sintassi man mano che le nuove versioni del sistema SAS sono state rese disponibili. Quanto diremo in questo paragrafo vale per la versione 5 del sistema SAS su mainframe, ma gi nella versione 6.03 del sistema SAS su PC sono presenti sostanziali innovazioni, che, certamente saranno trasferite anche nelle prossime versioni del sistema SAS su mainframe. In tutti i principali linguaggi sono sempre state presenti istruzioni che, sotto varie forme, hanno permesso di gestire in modo compatto aree di memoria, spesso contigue, contenenti dati omogenei (ad esempio la DIMENSION del FORTRAN, la OCCURS del COBOL, ecc.). Anche nel sistema SAS, esiste una dichiarazione simile, la ARRAY, che particolarmente utile in numerose applicazioni, dove occorre eseguire le stesse operazioni su molte variabili, sia numeriche che 150

non numeriche. Ad esempio supponiamo di leggere da un archivio 10 variabili numeriche che rappresentano delle risposte ad un questionario e di voler assegnare a ciascuna di esse valore mancante nel caso che contenga il valore 9. Un possibile passo di DATA che risolve questo semplice problema mostrato in figura 4.7.
DATA RIMAPPA; INFILE RISPOSTE; INPUT RISP1-RISP10; IF RISP1 = 9 THEN RISP1 = IF RISP2 = 9 THEN RISP2 = IF RISP3 = 9 THEN RISP3 = IF RISP4 = 9 THEN RISP4 = IF RISP5 = 9 THEN RISP5 = IF RISP6 = 9 THEN RISP6 = IF RISP7 = 9 THEN RISP7 = IF RISP8 = 9 THEN RISP8 = IF RISP9 = 9 THEN RISP9 = IF RISP10 = 9 THEN RISP10 RUN;

. . . . . . . . . =

; ; ; ; ; ; ; ; ; . ;

Figura 4.7: Programma che non fa uso della dichiarazione ARRAY La dichiarazione ARRAY permette di definire un insieme di variabili, tutte numeriche o tutte non numeriche, ciascuna delle quali diventa un elemento dell'array . I termini "array " e "vettore" spesso sono considerati sinonimi; ma esiste una sostanziale differenza. Usualmente in altri linguaggi si intende per vettore una serie di posizioni di memoria; nel sistema SAS per array si intende invece una sovrastruttura logica, che permette di individuare la singola variabile non pi con il proprio nome, ma facendo riferimento all'opportuno elemento dell'array con notevole risparmio di codice. Tuttavia gli array definiti in un passo di DATA non usano memoria aggiuntiva, e non compare alcuna traccia di essi nel PDV, n nella parte dati n in quella descrittiva di un file SAS. Esistono due diversi modi per poter referenziare un array: una "notazione implicita" ed una "notazione esplicita" introdotta nelle ultime versioni del sistema SAS. Verr esaminata in questo paragrafo solamente questa ultima notazione in quanto pi vicina al modo con cui vengono trattati i vettori in tutti gli altri linguaggi. La sintassi della dichiarazione ARRAY la seguente: ARRAY elementi ; dove: nome array pu essere qualunque nome SAS valido purch diverso dal nome di una funzione; n 151 <nome array > {n } [ $ ] [ lunghezza ]

un valore intero che rappresenta il numero di elementi dell'array e de- ve essere racchiuso fra parentesi graffe. Se al posto di n specificato "*" si lascia al sistema SAS il compito di calcolare il numero di elementi; $ indica che gli elementi dell'array sono tutti non numerici; lunghezza specifica la lunghezza degli elementi dell'array che non sono stati precedentemente definiti. Questa opzione non obbligatoria. Singoli elementi dell'array possono avere lunghezza diversa; elementi elenca le variabili che fanno parte dell'array . Debbono essere tutte numeriche o tutte non numeriche; elementi possono essere indicati in vari modi: si specificano tutti in modo esplicito in qualunque ordine; si specificano solo il primo e l'ultimo elemento di un array, separati da un trattino, se i loro nomi hanno un prefisso comune e terminano con un numero progressivo (crescente o decrescente); si specificano i nomi di due variabili, separati da un doppio trattino; in tal caso sono considerati elementi dell'array tutte le variabili contigue del PDV comprese fra quelle specificate. Esempi: ARRAY RISPOSTA {10} RISP1 RISP2 RISP3 RISP4 RISP5 RISP6 RISP7 RISP8 RISP9 RISP10 ; ARRAY RISPOSTA {10} RISP1-RISP10 ; /*identica alla precedente*/ ARRAY RISPOSTA { * } RISP10-RISP1 ; /*identica alle precedenti*/ ARRAY LETTERE {5} $ A B C D E; ARRAY CAR {*} $ NOME--SESSO ; /*comprende tutte le variabili gi definite nel PDV che si trovano fra NOME e SESSO; debbono essere tutte non numeriche */ L'esempio mostrato in figura 4.7 pu essere risolto pi semplicemente, utilizzando la dichiarazione ARRAY, come mostrato in figura 4.8. Da notare che nel PDV di questo passo di DATA non compare l'array RISPOSTA che, in funzione della sua definizione, serve solo a scrivere in modo pi compatto le singole variabili.

152

DATA RIMAPPA; DROP I ; INFILE RISPOSTE; ARRAY RISPOSTA {10} RISP1-RISP10 ; INPUT RISP1-RISP10 ; DO I = 1 TO 10 ; IF RISPOSTA(I) = 9 THEN RISPOSTA(I) = . ; END; RUN;

Cos ad esempio:
RISPOSTA(1) = . ; RISPOSTA(2) = . ; RISPOSTA(3) = . ;

equivalente a equivalente a equivalente a

RISP1 = . ; RISP2 = . ; RISP3 = . ;

solo perch nella dichiarazione ARRAY stata fatta questa associazione. Se invece la dichiarazione ARRAY viene scritta nel seguente modo:
ARRAY RISPOSTA {10} RISP10 RISP1 RISP2-RISP9 ;

allora:
RISPOSTA(1) = . ; RISPOSTA(2) = . ; RISPOSTA(3) = . ;

equivalente a equivalente a equivalente a

RISP10 = . ; RISP1 RISP2 = . ; = . ;

L'esempio mostrato in figura 4.8 potrebbe essere anche cos scritto:


DATA RIMAPPA; DROP I ; INFILE RISPOSTE; ARRAY RISPOSTA {*} RISP1-RISP10 ; INPUT RISP1-RISP10 ; DO I = 1 TO DIM(RISPOSTA) ; IF RISPOSTA(I) = 9 THEN RISPOSTA(I) = . ; END; RUN;

In questo caso il numero di elementi dell'array calcolato dal sistema SAS, e nella dichiarazione DO, la funzione DIM(RISPOSTA) fornisce come risultato proprio 10. Gli ARRAY possono essere usati anche per definire nuove variabili. Si abbia ad esempio un archivio che riporti per ogni mese dell'anno il numero di lavori eseguiti su un elaboratore. Si vuole conoscere la percentuale mensile rispetto al totale dei lavori eseguiti durante tutto l'anno. Un programma che risolve il problema mostrato in figura 4.9. Come si vede, vengono definite, all'interno del passo di DATA, 12 variabili numeriche di nome PC1, PC2, ..., PC12 contenenti le percentuali mensili di lavori eseguiti.

153

Da notare l'uso della funzione SUM, per calcolare il numero totale di lavori eseguiti durante l'anno, che ci salvaguarda dalla presenza di eventuali valori mancanti. La sintassi concisa della funzione possibile perch le variabili hanno tutte lo stesso prefisso.
DATA PERCENTO; DROP I MESE1-MESE12 TOTALE ; INFILE LAVORI ; INPUT ANNO MESE1-MESE12 ; TOTALE = SUM(OF MESE1-MESE12) ; ARRAY LAVORI {12} MESE1-MESE12 ; ARRAY PERC {12} PC1-PC12 ; DO I = 1 TO 12; PERC(I) = ( LAVORI(I) / TOTALE ) * 100 ; END ; PROC PRINT NOOBS; FORMAT PC1-PC12 4.1; TITLE 'ESEMPIO DI USO DELLA DICHIARAZIONE ARRAY'; RUN;

Figura 4.9: Uso della dichiarazione ARRAY per definire variabili Se le prime due righe di dati, relative agli anni 1980 e 1981, sono le seguenti :
1980 1981 1500 1400 1600 1800 2200 2500 1200 600 1800 2500 2800 3200 1800 1700 1900 2000 3000 3300 1400 750 2000 2800 3200 4000

il risultato della PROC PRINT sar il seguente:


ESEMPIO DI USO DELLA DICHIARAZIONE ARRAY ANNO PC1 PC2 PC3 PC4 PC5 PC6 PC7 PC8 PC9 PC10 PC11 PC12

1980 6.5 6.1 6.9 7.8 9.5 10.8 5.2 2.6 7.8 10.8 12.1 13.9 1981 6.5 6.1 6.8 7.2 10.8 11.8 5.0 2.7 7.2 10.1 11.5 14.4

4.5. Le conversioni fra dati numerici e dati non numerici


Come detto il sistema SAS gestisce solo due tipi di variabili: quelle numeriche e quelle non numeriche. La rappresentazione interna dei due tipi di variabili totalmente diversa; mentre quelle numeriche sono rappresentate in doppia precisione virgola mobile, quelle non numeriche occupano 1 posizione (byte ) per ogni carattere. Pu capitare nel corso di un passo di DATA di dover utilizzare una variabile definita non numerica in operazioni aritmetiche, o di effettuare ad esempio una operazione di concatenazione che coinvolge una variabile definita numerica.

154

Come reagisce il sistema SAS in queste Consideriamo ad esempio questo passo di DATA:

condizioni?

DATA COCKTAIL; INPUT LORDO SCONTO $ CAP CITTA $ ; NETTO = LORDO - (LORDO * SCONTO) ; LOCALITA = CAP || ' ' || CITTA ; CARDS; 1000000 .20 56100 PISA ; PROC PRINT NOOBS; TITLE 'ESEMPIO DI CONVERSIONI AUTOMATICHE'; RUN;

L'uscita della PROC PRINT la seguente:


ESEMPIO DI CONVERSIONI AUTOMATICHE LORDO 1000000 SCONTO .20 CAP 56100 CITTA PISA NETTO 800000 LOCALITA 56100 PISA

Leggendo i risultati, si vede che tutto ha funzionato perfettamente, ma nel SASLOG il sistema SAS avverte che sono state effettuate due conversioni: la prima relativa al contenuto della variabile SCONTO (da non numerico a numerico), la seconda relativa al contenuto della variabile CAP (da numerico a non numerico). Ecco una riproduzione parziale del SASLOG:
1 2 3 4 5 DATA COCKTAIL; INPUT LORDO SCONTO $ CAP CITTA $ ; NETTO = LORDO - (LORDO * SCONTO) ; LOCALITA = CAP || ' ' || CITTA ; CARDS;

NOTE: CHARACTER VALUES HAVE BEEN CONVERTED TO NUMERIC VALUES AT THE PLACES GIVEN BY: (LINE):(COLUMN) 3:29. NOTE: NUMERIC VALUES HAVE BEEN CONVERTED TO CHARACTER VALUES AT THE PLACES GIVEN BY: (LINE):(COLUMN) 4:17.

Si ripropone in questo caso l'amletico dilemma, che potrebbe suonare cos "correggere o non correggere?". In altre parole possiamo fidarci ciecamente del sistema SAS, in considerazione che i risultati si rivelano esatti, oppure opportuno prendere in seria considerazione gli ammonimenti riportati sul SASLOG? Per sciogliere questo dubbio, necessario capire in dettaglio il meccanismo che sta alla base della conversione dei dati. In particolare possiamo affrontare questo problema con due approcci diversi. 155

Il primo, o metodo implicito, consiste nel far effettuare le conversioni automaticamente al sistema SAS. Il secondo, o metodo esplicito, consiste nell'effettuare le conversioni quando ci necessario, utilizzando due funzioni : INPUT per convertire dati non numerici in dati numerici ; PUT per convertire dati numerici in dati non numerici.

Nei prossimi paragrafi analizzeremo questi metodi; spesso parleremo di "conversione di variabili", in quanto questa dizione di uso molto comune. Ci deve tuttavia intendersi come "conversione del contenuto delle variabili" nel senso che una variabile mantiene, dopo la conversione del contenuto, le stesse caratteristiche (numerica o non numerica) che aveva prima della conversione. Cos, nell'esempio precedente, la variabile CAP resta numerica mentre SCONTO resta non numerica anche dopo che sono state effettuate le conversioni.

4.5.1. Conversioni da variabili non numeriche a variabili numeriche


Il sistema SAS converte automaticamente una variabile non numerica in numerica quando questa viene usata in un contesto "numerico". Questo accade quando una variabile non numerica usata nei seguenti casi: viene assegnata ad una variabile numerica; viene utilizzata in operazioni aritmetiche; viene confrontata tramite un operatore logico (ad esempio >, <, =) con una variabile o costante numerica; viene usata in una funzione che prevede argomenti numerici. Tutte le volte che il sistema SAS esegue una conversione automatica, stampa un messaggio sul SASLOG; se poi la conversione della variabile da non numerica a numerica non produce un dato significativo, il sistema SAS scrive un messaggio di errore sul SASLOG, assegna a quella variabile valore mancante, e la variabile automatica _ERROR_ assume il valore 1. Ad esempio nel passo di DATA mostrato in figura 4.10, la variabile non numerica VARC viene sempre convertita correttamente in variabile numerica, mentre la conversione della variabile VARCERR genera un valore mancante. 156

DATA

CONVERTI; VARC = '100' ; VARCERR = 'MAMMA'; VARN = VARCERR + 100 ; VARN = VARC + 100 ; IF (VARC = 100) THEN VARN+1; VARN = VARC ; TOTALE = SUM(VARN,VARC);

/* /* /* /* /*

===> ===> ===> ===> ===>

VARN VARN VARN VARN TOTALE

= = = = =

. 200 201 100 200

*/ */ */ */ */

RUN;

Figura 4.10: Esempio di conversioni automatiche In generale si pu dire che il sistema SAS si comporta "secondo le aspettative" nella conversione da variabile non numerica a variabile numerica, senza arrivare a risultati imprevisti. La conversione esplicita avviene come detto tramite la funzione INPUT. La sintassi di questa funzione la seguente: INPUT (argomento, formato.) dove: argomento una variabile, costante o espressione di tipo non numerico; formato. un formato per leggere dati numerici. Questa funzione viene di norma usata per "leggere" l'argomento (non numerico) con un opportuno formato (numerico); ci causa la conversione della stringa specificata nell'argomento, da non numerica a numerica secondo le indicazioni del formato usato. Supponiamo ad esempio di voler calcolare l'et di due bambini, conoscendo la data di nascita, che tuttavia stata letta come una stringa di caratteri.
DATA NASCITE; INPUT NOME $10. NASCITA $8. ; CARDS; FRANCESCO 22/11/82 MONICA 26/11/78 ;

Una possibile soluzione del problema la seguente:


DATA ETA; SET NASCITE; ANNI = 1988 - YEAR(INPUT(NASCITA,DDMMYY8.)); RUN;

157

La funzione INPUT "legge" il contenuto della variabile non numerica NASCITA (che era stata digitata nella forma giorno/mese/anno) con un opportuno formato (DDMMYY8.) e lo converte in formato numerico; poich il formato utilizzato uno di quelli previsti per leggere le date, il risultato della funzione INPUT viene convertito dal sistema SAS come il numero di giorni fra la data "letta" ed il 1 Gennaio 1960. La funzione YEAR estrae perci il corretto anno di nascita (1982 e 1978 rispettivamente) e la variabile ANNI contiene effettivamente l'et (rispettivamente 6 e 10). E' formalmente corretto che l'argomento della funzione INPUT sia costituito anche da una variabile numerica; in tal caso se il formato con cui tale variabile viene "letta" fosse non numerico, si otterrebbe una conversione da variabile numerica a variabile non numerica. Questo uso della funzione INPUT assolutamente da evitarsi e per effettuare la conversione da variabile numerica a variabile non numerica raccomandato l'uso della funzione PUT.

4.5.2. Conversioni da variabili numeriche a variabili non numeriche


Il sistema SAS converte automaticamente una variabile numerica in non numerica nei seguenti casi: la variabile numerica viene assegnata ad una variabile non numerica. La variabile numerica viene prima convertita in non numerica usando il formato BESTc., dove "c" la lunghezza della variabile non numerica, poi allineata a destra ed infine completata di spazi fino ad arrivare alla lunghezza necessaria. Si ricorda che il formato BESTc. sceglie la migliore notazione possibile per visualizzare una variabile numerica, eventualmente ricorrendo anche ad arrotondamenti, in funzione delle posizioni disponibili. Esempio:
DATA BESTX; A='AF'; /* B='SAS'; /* C='GRAPH';/* N=1267; /* A=N ; /* VARIABILE NON NUMERICA LUNGA 2 */ VARIABILE NON NUMERICA LUNGA 3 */ VARIABILE NON NUMERICA LUNGA 5 */ VARIABILE NUMERICA LUNGA 8 */ A='**' 1267 E' CONVERTITO IN BEST2. MA IL SISTEMA SAS NON RIESCE A VISUALIZZARLO IN DUE POSIZIONI */ /* => B='1E3' 1267 E' CONVERTITO IN BEST3.*/ /* => C=' 1267' 1267 E' CONVERTITO IN BEST5.*/ => => => => =>

B=N ; C=N ; RUN;

la variabile numerica viene utilizzata con un operatore che richiede un valore non numerico (ad esempio l'operatore di concatenazione). In questo caso la variabile numerica viene 158

prima convertita in non numerica usando il formato BEST12., poi allineata a destra ed infine completata con spazi sulla sinistra; la variabile numerica viene usata in una funzione che prevede argomenti non numerici. Anche in questo caso la variabile numerica viene prima convertita in non numerica usando il formato BEST12., poi allineata a destra ed infine completata con spazi sulla sinistra.

Tutte le volte che il sistema SAS esegue una conversione automatica, stampa un messaggio sul SASLOG. Come si pu vedere il processo di conversione risulta pi complesso che nel caso precedente e pu causare dei risultati inattesi. Si consideri il seguente esempio:
DATA SORPRESA; CAP = 56100; CITTA = 'PISA'; MARCA = 'ALFA'; MODELLO = 33; VAR1 = CAP || CITTA; VAR2 = MARCA || MODELLO; PROC PRINT NOOBS; TITLE 'CHI L''AVREBBE MAI DETTO ?'; RUN;

La PROC PRINT produce la seguente uscita:


CHI L'AVREBBE MAI DETTO ? CAP CITTA MARCA ALFA MODELLO 33 VAR1 56100PISA VAR2 ALFA 33

56100 PISA

La variabile VAR1 lunga 16 caratteri (12 dovuti alla variabile CAP convertita nel formato "BEST12." e 4 alla variabile CITTA), ma il risultato quello atteso in quanto gli spazi di troppo vengono nascosti trovandosi a sinistra del valore 56100. Anche la variabile VAR2 lunga 16 caratteri (4 dovuti alla variabile MARCA e 12 alla variabile TIPO) ma in questo caso vengono evidenziati anche gli spazi aggiunti dal sistema SAS al momento della conversione della variabile MODELLO nel formato "BEST12." . Per risolvere correttamente questo problema ci sono due alternative: passare alla conversione esplicita per mezzo della funzione PUT, o integrare i risultati ottenuti dalla conversione implicita mediante l'utilizzo della funzione LEFT. La sintassi della funzione PUT la seguente: 159

PUT (argomento, formato.) dove: argomento pu essere una variabile, costante o espressione di tipo non numerico o numerico; formato deve essere un formato numerico se l'argomento numerico, un formato non numerico se l'argomento non numerico. In questo ultimo caso, la funzione non viene usata per effettuare una conversione di dati, ma per effettuare una conversione di formato. Il risultato della funzione PUT sempre una stringa di caratteri che allineata a destra se l'argomento numerico, o a sinistra se l'argomento non numerico; tale stringa contiene tante posizioni quante ne indica formato. Risolviamo l'esempio precedente con la funzione PUT.

DATA SORPRESA; CAP = 56100; CITTA = 'PISA'; MARCA = 'ALFA'; MODELLO = 33; VAR1 = PUT(CAP,5.) || CITTA; VAR2 = MARCA || PUT(MODELLO,2.); PROC PRINT NOOBS; RUN;

La PROC PRINT produce ora la seguente uscita:


CAP 56100 CITTA PISA MARCA ALFA MODELLO 33 VAR1 56100PISA VAR2 ALFA33

La funzione PUT(CAP,5.) crea la stringa lunga 5 posizioni '56100' mentre la funzione PUT(MODELLO,2.) crea la stringa lunga 2 posizioni '33'. La variabile VAR1 contiene ora perci 9 posizioni, e la variabile VAR2 ne contiene 6. La funzione LEFT, la cui sintassi : LEFT (argomento) semplicemente sposta gli spazi non significativi che si trovano alla sinistra dell'argomento, alla sua destra. Risolviamo ora l'esempio precedente usando sia la funzione PUT che la funzione LEFT: 160

DATA SORPRESA; CAP = 56100; CITTA = 'PISA'; MARCA = 'ALFA'; MODELLO = 33; VAR1 = PUT(CAP,5.) || CITTA; LENGTH VAR2 $ 6 ; VAR2 = MARCA || LEFT(MODELLO); PROC PRINT NOOBS; RUN;

La PROC PRINT produce la seguente uscita:


CAP 56100 CITTA PISA MARCA ALFA MODELLO 33 VAR1 56100PISA VAR2 ALFA33

La variabile VAR1 ancora lunga 9 caratteri ma la variabile VAR2 sarebbe invece lunga 200 caratteri in assenza della dichiarazione LENGTH. Un'utile applicazione delle funzioni INPUT e PUT quella di convertire date che sono state memorizzate in formato packed su archivi magnetici, in date secondo il formato SAS. Ad esempio supponiamo che su un archivio, puntato da DATI, sia stata memorizzata la data 31 Dicembre 1985 nel formato packed nella forma anno/mese/giorno (la data occupa 5 posizioni e, in notazione esadecimale, risulta cos memorizzata '019851231C'). Un possibile passo di DATA il seguente:
DATA PACKED; INFILE DATI; INPUT NDATA PD5. ; /* CDATA=PUT(NDATA,8.); /* SDATA=INPUT(CDATA,YYMMDD8.);/* NOFORM=SDATA; /* PROC PRINT NOOBS; FORMAT SDATA DDMMYY8.; /* RUN;

==> ==> ==> ==>

NDATA = 19851231 */ CDATA ='19851231'*/ SDATA = 9496 */ NOFORM = 9496 */

==> SDATA = 31/12/85 */

In sostituzione delle due dichiarazioni:


CDATA=PUT(NDATA,8.); SDATA=INPUT(CDATA,YYMMDD8.);

si poteva usare un'unica dichiarazione:


SDATA=INPUT(PUT(NDATA,8.),YYMMDD8.);

ponendo come argomento della INPUT la funzione PUT. 161

A conferma dei commenti inseriti nel programma, l'uscita della PROC PRINT il seguente:
NDATA 19851231 CDATA 19851231 SDATA 31/12/85 NOFORM 9496

Il valore 9496 rappresenta ovviamente il numero giorni che intercorrono fra il 31/12/1985 ed il 1/1/1960 .

162

5. Gestione degli archivi

5.1. La lettura e scrittura degli archivi in SAS


Il sistema SAS garantisce una grande flessibilit nella gestione dei dati; possibile, in ogni passo di DATA, leggere o scrivere uno o pi archivi. La figura 5.1 mostra tutte le possibili combinazioni che il sistema SAS permette di gestire. Per archivio non SAS" o "grezzo" si intende un qualunque file organizzato secondo i metodi di accesso pi diffusi (sequenziali, partitioned, ecc.), e, come caso particolare, un file di stampa.

Archivio non SAS

INPUT INFILE CARDS Passo di DATA SET MERGE UPDATE

Archivio non SAS PUT FILE OUTPUT (automatico) Archivio SAS

Archivio SAS

Figura 5.1: Possibili dichiarazioni per l'entrata/uscita del passo di DATA In funzione degli archivi trattati (SAS o grezzi, in lettura o in scrittura) si possono schematizzare quattro possibili tipi di passo di DATA: lettura da archivi non SAS e scrittura su archivi SAS. Passi di DATA di questo tipo sono indispensabili per convertire archivi grezzi in equivalenti file SAS. Le dichiarazioni necessarie per leggere archivi non SAS sono: INFILE <puntatore_file>; 163

indica l'archivio non SAS che deve essere letto; puntatore_file un nome di comodo lungo al massimo 8 caratteri, che deve essere stato precedentemente associato in modo esplicito al nome completo dell'archivio ed alla sua ubicazione fisica. Nel caso che i dati siano messi in coda dello stesso passo di DATA, essi debbono essere preceduti da una dichiarazione CARDS e la dichiarazione INFILE pu essere omessa. INPUT la dichiarazione che indica come debbono essere letti i dati; descritta dettagliatamente nel capitolo 2.

La dichiarazione necessaria per scrivere una osservazione su un archivio SAS la OUTPUT. Questa dichiarazione pu essere scritta in un passo di DATA esplicitamente, oppure pu essere omessa; in quest'ultimo caso essa verr eseguita in modo implicito alla fine del passo. La dichiarazione OUTPUT stata gi esaminata nel capitolo 2; la dichiarazione INFILE verr esaminata in dettaglio in questo capitolo. lettura da archivi SAS e scrittura su archivi SAS. Questo tipo di passo di DATA viene utilizzato per effettuare trasformazioni di archivi SAS gi esistenti, quali eliminazione o aggiunta di osservazioni e/o di variabili. Le dichiarazioni con cui vengono lette le osservazioni da un archivio SAS sono SET, MERGE ed UPDATE; esse verranno esaminate in dettaglio in questo capitolo. lettura da archivi SAS e scrittura su archivi non SAS. Questo tipo di passo di DATA viene utilizzato principalmente per produrre tabulati personalizzati, nel caso in cui le procedure SAS standard non siano sufficienti per risolvere particolari esigenze dell'utente. Un'altra applicazione possibile quella di creare archivi di tipo tradizionale su supporti magnetici che possano essere successivamente elaborati da programmi scritti in linguaggi diversi dal SAS. Come gi detto, gli archivi SAS sono letti utilizzando le dichiarazioni SET, MERGE o UPDATE, mentre le dichiarazioni necessarie per scrivere dei record su supporti magnetici o per produrre prospetti di stampa sono: FILE <puntatore_file>; indica dove l'archivio deve essere scritto; puntatore_file, in modo analogo alla INFILE, un nome di comodo lungo al massimo 8 caratteri, che deve essere stato precedentemente associato esplicitamente al nome completo dell'archivio da scrivere. Nel caso di stampe, al posto di puntatore_file deve essere specificato PRINT. 164

PUT

la dichiarazione che indica come i dati debbono essere scritti. La sintassi analoga a quella della dichiarazione INPUT.

Le dichiarazioni FILE e PUT verranno esaminate in dettaglio nel capitolo 6 che tratta i vari metodi disponibili per poter produrre rapporti. lettura da archivi non SAS e scrittura su archivi non SAS. Questo tipo di passo di DATA utilizza esclusivamente il sistema SAS come un normale linguaggio di programmazione. Le dichiarazioni da usare sono INFILE ed INPUT per leggere i dati, FILE e PUT per scriverli. Le applicazioni sviluppate in questo modo, potrebbero essere scritte con un qualunque altro linguaggio di programmazione. Sarebbe interessante esplorare la tipologia di applicazioni per le quali preferibile scegliere il linguaggio SAS rispetto ad altri linguaggi, nonch i motivi che hanno indotto molte aziende ed enti pubblici ad implementare in SAS soprattutto le nuove applicazioni, anche a costo di notevoli investimenti rivolti alla formazione del personale. Riteniamo tuttavia che questa discussione esuli dagli obiettivi che questo libro si prefigge, perch essa comporterebbe di analizzare in estremo dettaglio le differenze che esistono fra il linguaggio SAS e gli altri linguaggi pi diffusi; ma questa dissertazione non interesserebbe certamente l'utente applicativo mentre siamo certi che i programmatori che utilizzano altri linguaggi sono in grado di fare questa analisi per proprio conto.

5.2.

La lettura degli archivi non SAS

Il sistema SAS pu essere usato per leggere archivi residenti sia su nastro che su disco, in funzione del sistema operativo sotto cui installato. Ad esempio nel sistema operativo MVS possibile leggere in modo sequenziale archivi organizzati in modo partitioned, ISAM, BDAM, VSAM, ecc.. Gli archivi di tipo VSAM possono inoltre essere letti anche per chiave. La dichiarazione che deve essere usata nel sistema SAS per leggere qualunque tipo di archivio, indipendentemente dalla sua organizzazione e dalla sua allocazione, la INPUT. Non ci sono limitazioni al numero di archivi che possono essere gestiti in un passo di DATA. A differenza di altri linguaggi, la dichiarazione INPUT non prevede al suo interno nessuna indicazione relativa all'archivio da cui debbono essere prelevati i dati. Pertanto, quando una dichiarazione INPUT viene eseguita, il sistema SAS deve gi conoscere la ubicazione dell'archivio da cui debbono essere letti i dati. Vi sono due possibilit. 165

I dati vengono inseriti direttamente all'interno del passo di DATA. In questo caso essi vanno scritti in coda al passo stesso preceduti da una dichiarazione CARDS. Tale dichiarazione non eseguibile ed ha la sola funzione di avvertire il compilatore dell'inizio dei dati. In questo caso ogni linea da leggere pu contenere al massimo 80 posizioni. Esempio:
DATA; ..... dichiarazioni SAS ........... INPUT ...elenco di variabili... ; ..... altre dichiarazioni SAS ..... CARDS; ...... dati ....... ;

I dati si trovano su uno o pi archivi esterni. In questo caso ogni archivio deve avere una corrispondente dichiarazione INFILE che crei un aggancio fra esso ed il sistema SAS. Ogni dichiarazione di INPUT legge dall'archivio che stato indirizzato dalla dichiarazione INFILE pi recentemente eseguita. A differenza della CARDS, la dichiarazione INFILE eseguibile, come mostrato nell'esempio di figura 5.2.
DATA; INFILE CARDS; INPUT CODICE; IF CODICE = 1 THEN

/*legge da CARDS */ DO; INFILE DATI1; INPUT ...; /*legge da DATI1 */ END; ELSE DO; INFILE DATI2; INPUT...; /*legge da DATI2 */ END;

CARDS; 1 2 3 RUN;

Figura 5.2: Esempio di INFILE eseguite in modo condizionale La prima INPUT legge una riga di dati situati dopo la CARDS ed attribuisce a CODICE il valore specificato. In funzione di questo valore viene letto un record dall'archivio non SAS indirizzato da DATI1 (se CODICE uguale ad 1) o dall'archivio non SAS indirizzato da DATI2 (se CODICE diverso da 1). I nomi DATI1 e DATI2 sono scelti dall'utente in modo arbitrario; essi per, prima della esecuzione della INPUT, debbono essere associati agli archivi da leggere per mezzo di opportuni comandi di sistema che variano in funzione del sistema operativo sotto cui

166

si trova il SAS4. Tali comandi possono anche essere inseriti direttamente nel programma SAS mediante la dichiarazione X.

Ad esempio sotto MVS/TSO dovranno essere dati i comandi:


X ALLOCATE FI (DATI1) DATASET (.. <nome archivio> ..) SHR; X ALLOCATE FI (DATI2) DATASET (.. <nome archivio> ..) SHR;

mentre sotto VM/CMSdovranno essere dati i seguenti comandi:


X FILEDEF DATI1 DISK ... <nome archivio> ... ; X FILEDEF DATI2 DISK ... <nome archivio> ... ;

5.3.

La dichiarazione INFILE

In sintesi la sintassi della dichiarazione INFILE la seguente: INFILE <puntatore_file>[opzioni] ; dove: puntatore_file un nome valido SAS, scelto arbitrariamente dall'utente, che in precedenza stato associato in modo esplicito all'archivio grezzo che deve essere letto. Nel caso di dati codificati per mezzo della CARDS, la dichiarazione INFILE necessaria solo se si devono leggere nello stesso passo di DATA anche archivi esterni, come mostrato in figura 5.2, oppure quando debbono essere specificate delle opzioni; in tal caso, al posto di puntatore_file, deve essere obbligatoriamente specificato CARDS. opzioni nessuna di esse obbligatoria; ne segnaliamo alcune fra le pi utilizzate: END=variabile definisce una variabile SAS che vale sempre 0 escluso dopo che stato letto l'ultimo record di un archivio; in tal caso essa vale 1. Si noti che questa opzione, abbinata con CARDS, non funziona se il programma viene eseguito in ambiente interattivo (sotto DMS). La variabile definita dopo END compare nel PDV, ma ne viene fatto un DROP automatico, per cui non copiata nel file SAS di uscita. In figura 5.3 mostrato un esempio di uso di questa opzione. La variabile FINEDATI vale 1
4 Vedere l'appendice B contenente esempi dei comandi di sistema per leggere e

scrivere archivi esterni negli ambienti MVS/TSO, VM/CMS, VMS, DOS/VSE e PC.

167

dopo la lettura della seconda riga dati. Richiamiamo l'attenzione sul fatto che, a differenza di quanto avviene nella maggior parte degli altri linguaggi evoluti e come evidenziato dagli schemi di figura 2.8, il passo termina quando il sistema SAS tenta di leggere record successivi all'ultimo presente nell'archivio. Ne deriva che il sistema deve effettuare l'avvertimento in anticipo affinch esso risulti utile.
DATA LEGGI; INFILE CARDS END=FINEDATI; INPUT A B ; N+1; /* dichiarazione SUM */ IF FINEDATI = 1 THEN PUT 'HO LETTO ' N ' RECORD'; CARDS; 1 2 3 4 RUN;

Figura 5.3: Esempio di uso della opzione END In questo particolare caso al posto del contatore N poteva essere usata la variabile automatica _N_, risparmiando l'istruzione di incremento, come si vede in figura 5.4.
DATA LEGGI; INFILE CARDS END=FINEDATI; INPUT A B ; IF FINEDATI = 1 THEN PUT 'HO LETTO ' _N_ ' RECORD'; CARDS; 1 2 3 4 RUN;

Figura 5.4: Esempio alternativo di uso della opzione END Entrambi gli esempi scrivono 2 osservazioni e stampano su SASLOG la stringa : 'HO LETTO 2 RECORD' . EOF=etichetta indica una etichetta (non una variabile come l'opzione END), a cui il programma deve saltare quando viene raggiunta la fine file (EOF). Mentre l'opzione END pone la variabile specificata ad 1 dopo aver letto l'ultimo record, la opzione EOF esegue il salto all'etichetta specificata quando la INPUT tenta di leggere da un archivio che non ha pi record. Questa opzione sempre valida anche quando abbinata a CARDS. La figura 5.5 mostra 168

come si trasforma l'esempio di figura 5.3, con l'opzione EOF. Al terzo ciclo del passo di DATA, quando il tentativo di leggere la terza riga dati fallisce, il programma salta alla etichetta FINEDATI e stampa su SASLOG la stringa: 'HO LETTO 2 RECORD'. Senza la dichiarazione RETURN si otterrebbe una riga di stampa per ogni record letto. La dichiarazione OUTPUT si rende necessaria per evitare la scrittura di una terza osservazione composta solamente di valori mancanti.
DATA LEGGI; INFILE CARDS EOF=FINEDATI; INPUT A B ; N+1; /* dichiarazione SUM */ OUTPUT; RETURN; FINEDATI: PUT 'HO LETTO ' N ' RECORD'; CARDS; 1 2 3 4 RUN;

Figura 5.5: Stesso esempio di figura 5.3 con opzione EOF In figura 5.6 viene mostrato come si trasforma invece l'esempio di figura 5.4:
DATA LEGGI; INFILE CARDS EOF=FINEDATI; INPUT A B ; OUTPUT; RETURN; FINEDATI: _N_ = _N_ - 1 ; PUT 'HO LETTO ' _N_ ' RECORD'; CARDS; 1 2 3 4 RUN;

Figura 5.6: Stesso esempio di figura 5.4 con opzione EOF Si noti la dichiarazione "_N_=_N_-1", perch l'opzione EOF scatta al terzo ciclo, nel quale _N_ vale 3. Anche in questo caso si deve inserire una dichiarazione OUTPUT per evitare la scrittura di una osservazione tutta composta di valori mancanti. MISSOVER indica che deve essere assegnato valore mancante a tutte le variabili a cui non stato assegnato alcun 169

valore quando una dichiarazione di INPUT raggiunge la fine del record corrente. Ad esempio il passo di DATA di figura 5.7 tenta di leggere tre dati per ogni riga, ma nella seconda ne trova solo due. L'anomalia segnalata su SASLOG con il seguente messaggio, indicante che il sistema andato a riga nuova quando non ha trovato tutti i dati richiesti sulla riga corrente:
NOTE: SAS WENT TO A NEW LINE WHEN INPUT STATEMENT REACHED PAST THE END OF A LINE. DATA ; INPUT A B C; CARDS; 1 2 3 4 5 6 7 8 PROC PRINT; RUN;

Figura 5.7: Esempio di INPUT a lista con dati mancanti La PROC PRINT produce di conseguenza, la seguente uscita:
OBS 1 2 A 1 4 B 2 5 C 3 6

Utilizzando l'opzione MISSOVER nell'esempio di figura 5.7, otteniamo:


DATA ; INFILE CARDS MISSOVER; INPUT A B C; CARDS; 1 2 3 4 5 6 7 8 PROC PRINT; RUN;

Cos modificato il passo di DATA non produce su SASLOG alcun messaggio. La PROC PRINT produce ora la seguente uscita:
OBS 1 2 3 A 1 4 6 B 2 5 7 C 3 . 8

170

STOPOVER

con questa opzione, simile alla MISSOVER, si chiede al sistema SAS di sospendere l'esecuzione del passo quando una dichiarazione di INPUT raggiunge la fine del record senza aver trovato dei valori da assegnare a tutte le variabili. Utilizzando l'opzione STOPOVER nell'esempio di figura 5.7 otteniamo:
DATA ; INFILE CARDS STOPOVER; INPUT A B C; CARDS; 1 2 3 4 5 6 7 8 PROC PRINT; RUN;

Su SASLOG comparir il seguente messaggio, prodotto durante l'elaborazione della seconda riga di dati:
ERROR:INPUT STATEMENT EXCEEDED RECORD LENGTH INFILE 'CARDS' OPTION STOPOVER SPECIFIED

La PROC PRINT non viene eseguita se il programma SAS viene eseguito in modo non interattivo o batch. Produce invece la seguente uscita se il programma viene eseguito in modo interattivo:
OBS 1 A 1 B 2 C 3

N=numero

definisce il numero di righe di cui composto l'input buffer. Questa opzione necessaria quando nella dichiarazione INPUT compare il puntatore assoluto di riga seguito non da una costante ma da una variabile; se questa opzione non viene specificata, l'input buffer sar composto di una sola riga.

5.3.1. Lettura da archivi non SAS con un diverso numero di record


La lettura di archivi non SAS, richiede una qualche attenzione nel caso che si abbiano in ingresso due o pi archivi con un numero diverso di record. In tal caso, la prima dichiarazione INPUT che fallisce per fine file, causa il termine del passo di DATA. 171

Supponiamo ad esempio che due archivi indirizzati da DATIA e DATIB abbiano rispettivamente due e quattro record :
ARCHIVIO "DATIA" 10 30 20 40 ARCHIVIO "DATIB" 100 300 500 700 200 400 600 800

Il passo di DATA mostrato di seguito legge, durante i primi due cicli, due record da entrambi gli archivi e scrive le relative osservazioni sul file SAS DOPPIO. Al terzo ciclo, scatta la condizione di EOF sul file DATIA, ed il passo termina, senza scrivere la terza osservazione.
DATA DOPPIO ; INFILE DATIA; INPUT VAR1 VAR2; INFILE DATIB; INPUT VAR3 VAR4; PROC PRINT NOOBS; RUN;

La PROC PRINT produce pertanto la seguente stampa:


VAR1 10 30 VAR2 20 40 VAR3 100 300 VAR4 200 400

Se si vuole leggere interamente anche il secondo archivio, si deve aggiungere l'opzione END ad entrambe le dichiarazioni INFILE.
DATA DOPPIO ; IF EOFDATIA = 1 AND EOFDATIB = 1 THEN STOP; IF EOFDATIA = 0 THEN DO; INFILE DATIA END = EOFDATIA; INPUT VAR1 VAR2; END; IF EOFDATIB = 0 THEN DO; INFILE DATIB END = EOFDATIB; INPUT VAR3 VAR4; END; PROC PRINT; RUN;

La variabile EOFDATIA (la scelta del nome del tutto arbitraria), assume il valore 1 durante la lettura del secondo record e mantiene questo valore fino al termine del programma. La variabile EOFDATIB assume invece il valore 1 durante la lettura del quarto record. 172

Quando il passo di DATA viene eseguito la quinta volta termina in quanto le condizioni specificate nella prima dichiarazione del passo di DATA sono entrambe verificate. La PROC PRINT ora produce la seguente stampa:
OBS 1 2 3 4 VAR1 10 30 . . VAR2 20 40 . . VAR3 100 300 500 700 VAR4 200 400 600 800

5.4. Complementi della dichiarazione INPUT a lista


Nel capitolo 2 si sono gi esaminate le principali caratteristiche della dichiarazione INPUT. In particolare sono stati descritti i tre tipi di INPUT possibili: a lista, a colonne e a formati. Aggiungiamo ora alcuni esempi relativi alla INPUT a lista, il cui uso rappresenta il sistema pi semplice per leggere dati digitati direttamente da terminale. Ricordiamo che le caratteristiche standard della INPUT a lista sono le seguenti: i dati devono essere separati da uno o pi spazi; il sistema SAS ricerca in ogni riga il primo carattere diverso da spazio e prosegue a leggere fino al successivo spazio. Il valore cos determinato viene assegnato alla prima variabile specificata. Questo processo prosegue fino a quando non stato assegnato un valore a tutte le variabili; se una riga contiene un numero di dati maggiore delle variabili specificate nella dichiarazione INPUT, i valori in eccesso sono ignorati; se invece i dati risultano inferiori alle variabili specificate, il sistema SAS scandir la riga successiva per trovarvi i valori che mancano al completamento della lettura (a meno che siano specificate le opzioni MISSOVER o STOPOVER); non possibile leggere variabili non numeriche che hanno spazi al loro interno o sono pi lunghe di 8 posizioni. In figura 5.8 riportiamo l'esempio gi utilizzato nel paragrafo 2.7.2 nel quale sono stati cambiati alcuni dati. 173

DATA ERRORI; INPUT NOME $ COGNOME $ SESSO $ ETA ALTEZZA; CARDS; Massimiliano Aloia M 36 1.78 Luca Di Montezemolo M 38 1.80 Elia Biorci . 38 Anna Neri F 28 1.68 Gina Rossi F 32 1.65 ; PROC PRINT NOOBS; RUN;

Figura 5.8: Esempio di INPUT a lista In figura 5.9 viene mostrato il risultato della PROC PRINT, che una specie di campionario degli errori a cui si pu andare incontro usando in modo troppo disinvolto la INPUT a lista.
NOME Massimil Luca Elia Gina COGNOME Aloia Di Biorci Rossi SESSO M Montezem F ETA 36 . 38 32 ALTEZZA 1.78 38.00 . 1.65

Figura 5.9: Uscita del programma di figura 5.8 Nella prima riga il nome "Massimiliano" stato troncato a 8 caratteri. Per correggere questo errore si deve specificare in modo esplicito la lunghezza della variabile NOME con una dichiarazione LENGTH.. Nella seconda riga, oltre al cognome pi lungo di 8 posizioni, si riscontra un secondo tipo di errore: viene a mancare la corrispondenza voluta fra valori e variabili a causa dello spazio compreso nel cognome. Per ovviare a questo problema , introduciamo il modificatore di formato "&". Esso permette di leggere dati non numerici che contengono uno spazio al loro interno, a patto che il valore da leggere termini con almeno due spazi anzich uno. Il modificatore "&" ci permette inoltre di associare alla INPUT a lista un qualunque formato valido di lettura. Non si deve confondere per la INPUT con formati con la INPUT a lista con associato un formato; nel primo caso il dato viene ricercato in un campo ben preciso e definito dai puntatori di colonna (espliciti o impliciti); nel secondo caso i valori vengono individuati con le regole della INPUT a lista. Per dare un'idea di questa differenza consideriamo l'esempio seguente formato da due passi di DATA, entrambi corretti, che 174

leggono gli stessi dati; il primo passo utilizza una INPUT a lista con il modificatore "&" il secondo una INPUT con formati.
DATA LISTA; INPUT COGNOME & $20. ETA PESO; /*INPUT A LISTA*/ CARDS; DI MONTEZEMOLO 20 65 RUBERTI 77 83.5 ; DATA FORMATI; INPUT COGNOME $20. ETA PESO; /*INPUT A FORMATI*/ CARDS; DI MONTEZEMOLO 20 65 RUBERTI 77 83.5 ;

Entrambi i passi riservano nel PDV (e quindi nell'archivio SAS) 20 posizioni alla variabile COGNOME; per, la INPUT a formati attribuir alla variabile COGNOME sempre i primi 20 caratteri di ogni riga dati, mentre la INPUT a lista fermer la scansione non appena avr trovato nella riga dati almeno due spazi consecutivi. Si ottiene cos un doppio vantaggio: leggere con il formato necessario e mantenere il tracciato libero. La terza riga dati di figura 5.8 contiene solo 4 valori, al posto di 5, ed il sistema SAS preleva il quinto dalla riga successiva (il valore "Anna" viene assegnato alla variabile numerica ALTEZZA e viene convertito in valore mancante). I rimanenti dati della riga sono persi perch durante il successivo ciclo del passo di DATA, la INPUT legger la riga seguente. Per ovviare a questo errore sufficiente specificare la opzione MISSOVER (o STPOVER) nella INFILE. Per far questo si rende necessario specificare una dichiarazione INFILE anche se i dati sono presenti all'interno del passo di DATA. Vediamo quindi di riscrivere il passo di DATA di figura 5.8, tenendo conto delle considerazioni fatte:
DATA VABENE; LENGTH NOME $ 20 ; INFILE CARDS MISSOVER ; INPUT NOME $ COGNOME & $20. SESSO $ ETA ALTEZZA; CARDS; Massimiliano Aloia M 36 1.78 Luca Di Montezemolo M 38 1.80 Elia Biorci . 38 Anna Neri F 28 1.68 Gina Rossi F 32 1.65 PROC PRINT NOOBS; RUN;

Il risultato della PROC PRINT, ora corretto, e viene mostrato in figura seguente. 175

NOME Massimiliano Luca Elia Anna Gina

COGNOME Aloia Di Montezemolo Biorci Neri Rossi

SESSO M M F F

ETA 36 38 38 28 32

ALTEZZA 1.78 1.80 . 1.68 1.65

5.5.

Lettura di archivi gerarchici

In molte applicazioni capita di dover leggere archivi organizzati in modo gerarchico, cio formati da uno o pi record di testata seguiti da uno o pi record di dettaglio. Consideriamo ad esempio il seguente problema: in un archivio su disco sono registrati i dati relativi a movimenti di conto corrente. Per ciascun correntista il primo record (contrassegnato da una 'A' in colonna 1) contiene il nome e cognome del correntista, il numero del conto ed il saldo. Di seguito sono registrati tutti i movimenti effettuati dal correntista. Una 'P' in colonna 1 indica un prelievo, una 'V' un versamento. Vediamo in figura 5.10 un estratto di questo archivio.
A SIMONE DE MARTINO 0749/4379 2500000 V 02/01/88 300000 P 03/01/88 1000000 P 03/02/88 500000 P 31/01/88 100000 A FRANCESCO ROSSI 1111/56480J 50000000 A GIUSEPPE BATTISTINI 9999/75438H 2000000 V 31/12/87 1000000 P 10/01/88 5000000 ....................

Figura 5.10: Qualche record dell'archivio dei conti correnti Come si vede il numero di record di dettaglio variabile, ed in alcuni casi addirittura assente. Si noti il formato libero del tracciato, con il cognome seguito da due spazi. Il sistema SAS mette a disposizione una interessante opzione della dichiarazione INPUT che permette in modo semplice la lettura di questo tipo di archivi. Essa consiste nell'aggiunta di un carattere @ che deve essere specificato immediatamente prima del termine della dichiarazione INPUT. Normalmente, ogni volta che viene eseguita una dichiarazione INPUT, viene caricata nell'input buffer la riga dati successiva ed il puntatore di colonna viene reimpostato ad 1. Quando nella dichiarazione INPUT viene specificato il simbolo "@", il puntatore di colonna ed il record letto vengono mantenuti, cos che l'esecuzione di un'altra dichiarazione INPUT causa la "rilettura" dello stesso record a partire dalla ultima colonna letta. Il record viene rilasciato, cio una successiva dichiarazione INPUT legger il 176

record successivo, dopo che: stata eseguita una dichiarazione INPUT senza @ finale; terminato un ciclo del passo di DATA, in modo implicito o esplicito (per mezzo di una dichiarazione DELETE o RETURN). Si noti che una nuova riga dati viene caricata nell'input buffer se viene rilevata una condizione di "fine record" cio se si tenta di leggere una colonna che va oltre la lunghezza della riga dati. Si supponga ad esempio di dover leggere un archivio dati, indirizzato da NUMERI i cui record sono lunghi 80 caratteri. Il seguente programma, durante la prima esecuzione, si comporta come descritto nei commenti:
DATA GRILLO; INFILE NUMERI; INPUT COL @ ; /*legge la prima riga dati */ INPUT @COL PRIMO 1.; /*legge alla colonna COL della prima riga se il valore di COL < 80 o alla colonna 1 della seconda riga se > 80 */ INPUT ULTIMO 5.; /*legge la 2a o la 3a riga dati a partire da colonna 1, in funzione della INPUT precedente */ RUN;

Quando il passo di DATA viene eseguito tutte le altre volte, la prima dichiarazione INPUT legger sempre il record successivo a quello letto dalla ultima INPUT del ciclo precedente. Consideriamo di nuovo il file dei conti correnti di figura 5.10. Scriviamo un passo di DATA che crei un archivio SAS, dal quale poter ottenere una stampa dettagliata dei prelievi effettuati su ogni conto corrente durante il mese di Gennaio 1988.
DATA PRELIEVI ; LENGTH CONTO $ 15 ; DROP TIPO; RETAIN CONTO NOME; /*serve per prelievi multipli*/ INFILE ESTRATTI STOPOVER ; INPUT TIPO $1. @; /* legge bloccando il record */ IF TIPO = 'A' THEN /* Se un record di testata..*/ INPUT NOME & $40./*..allora leggi NOME e CONTO */ CONTO $ ; /* altrimenti esegui una IF ..*/ IF TIPO = 'P'; /*.. subsetting sui prelievi e*/ INPUT @3 DATA DDMMYY8. IMPORTO;/*leggi DATA e IMPORTO*/ IF YEAR(DATA) = 1988 /*IF subsetting su anno... */ & MONTH(DATA) = 1; /* ... e mese */ RUN;

I commenti del programma sono sufficienti a spiegarne il funzionamento. Si noti solamente che la dichiarazione RETAIN 177

serve nel caso che ci siano pi prelievi su un conto. Senza di essa, nelle osservazioni successive al primo prelievo, i valori delle variabili CONTO e NOME sarebbero mancanti. Scriviamo ora un passo di PROC per stampare l'archivio SAS PRELIEVI:
PROC PRINT DATA=PRELIEVI NOOBS ; FORMAT DATA DDMMYY8. ; VAR NOME CONTO DATA IMPORTO ;

RUN;

L'uscita della PROC PRINT la seguente:


NOME SIMONE DE MARTINO SIMONE DE MARTINO GIUSEPPE BATTISTINI CONTO 0749/4379 0749/4379 9999/75438H DATA 03/01/88 31/01/88 10/01/88 IMPORTO 1000000 100000 5000000

Si vuole ora creare un archivio SAS contenente una osservazione per ogni conto corrente con il saldo aggiornato.
DATA SALDI ; LENGTH CONTO $ 15 ; KEEP CONTO SALDO ; RETAIN CONTO ; /* serve per conti con pi movimenti */ INFILE ESTRATTI STOPOVER /* EOF=1 se viene END=EOF; letto l'ultimo record */ INPUT TIPO $1. @; /* blocca il record */ IF TIPO = 'A' /* se un nuovo conto */ THEN DO; IF _N_ > 1 /*scrive saldo conto pre- */ THEN OUTPUT; /*cedente escluso 1a volta*/ INPUT NOME & $40. /* e legge il nuovo nome */ CONTO $ SALDO;/* conto e saldo */ END; ELSE DO; /*se non un nuovo conto*/ INPUT @12 IMPORTO 12.; /* legge importo e */ IF TIPO = 'V' /* aggiorna saldo */ THEN SALDO + IMPORTO; /* dichiaraz. SUM */ ELSE SALDO +(-IMPORTO); /* dichiaraz. SUM */ END; IF EOF=1 THEN OUTPUT; /*scrive saldo ultimo conto */ PROC PRINT DATA=SALDI NOOBS ; TITLE 'SITUAZIONE SALDI'; VAR CONTO SALDO ; RUN;

L'uscita della PROC PRINT il seguente:

178

SITUAZIONE SALDI CONTO 0749/4379 1111/56480J 9999/75438H SALDO 1200000 50000000 -2000000

5.6.

Uso del doppio @@

Quando i dati vengono digitati direttamente su terminale, pu risultare utile non solo scrivere in formato libero, separando i singoli valori con spazi, ma anche poter riunire su una stessa riga i dati per diverse osservazioni. Analogamente al singolo "@", quando nella dichiarazione INPUT viene specificato il doppio @@, il puntatore di colonna ed il record letto vengono mantenuti cos che l'esecuzione di un'altra dichiarazione INPUT causa la rilettura dello stesso record a partire dalla ultima colonna letta. Il record viene rilasciato, cio una successiva dichiarazione INPUT legger il record successivo, dopo che: stata eseguita una dichiarazione INPUT senza @ finale ; stata eseguita una dichiarazione INPUT con un @ finale ; viene incontrata la fine del record. La differenza con il singolo "@" consiste nel fatto che il blocco della riga dati continua anche se il ciclo di DATA ricomincia. Ad esempio il seguente programma:
DATA DOPPIOAT; INPUT CITTA $ TEMPMIN TEMPMAX @@ ; CARDS; MILANO -2 6 TORINO 0 7 GENOVA 6 12 BOLOGNA 1 5 ROMA 7 12 NAPOLI 6 15 BARI 9 15 PALERMO 14 20 CAGLIARI 9 13 ; PROC PRINT NOOBS SPLIT=*; TITLE 'TEMPERATURE MINIME E MASSIME'; LABEL TEMPMIN='TEMPERATURA*MINIMA'; LABEL TEMPMAX='TEMPERATURA*MASSIMA'; RUN;

179

fornisce l'uscita mostrata di seguito:


TEMPERATURE MINIME E MASSIME CITTA TEMPERATURA MINIMA -2 0 6 1 7 6 9 14 9 TEMPERATURA MASSIMA 6 7 12 5 12 15 15 20 13

MILANO TORINO GENOVA BOLOGNA ROMA NAPOLI BARI PALERMO CAGLIARI

La stessa uscita si ottiene anche se i dati sono non allineati:


DATA DOPPIOAT; INPUT CITTA $ TEMPMIN TEMPMAX @@ ; CARDS; MILANO -2 6 TORINO 0 7 GENOVA 6 12 BOLOGNA 1 5 ROMA 7 12 NAPOLI 6 15 BARI 9 15 PALERMO 14 20 CAGLIARI 9 13 RUN;

o se in ciascun riga non compare lo stesso numero di citt come mostrato nel prossimo programma:
DATA DOPPIOAT; INPUT CITTA $ TEMPMIN TEMPMAX @@ ; CARDS; MILANO -2 6 TORINO 0 7 GENOVA 6 12 BOLOGNA 1 5 ROMA 7 12 NAPOLI 6 15 BARI 9 15 PALERMO 14 20 CAGLIARI 9 13 RUN;

o se infine i dati sono codificati tutti di seguito.


DATA DOPPIOAT; INPUT CITTA $ TEMPMIN TEMPMAX @@ ; CARDS; MILANO -2 6 TORINO 0 7 GENOVA 6 12 BOLOGNA 1 5 ROMA 7 12 NAPOLI 6 15 BARI 9 15 PALERMO 14 20 CAGLIARI 9 13 RUN;

5.7. Lettura di archivi SAS con la dichiarazione SET

180

Nel capitolo 2 abbiamo visto l'uso della dichiarazione SET per leggere, in un passo di DATA, archivi SAS. Ci siamo limitati in quella sede a leggere un solo archivio in modo sequenziale. Esaminiamo ora le possibili estensioni della dichiarazione SET. Il programma di figura 5.11 riprende i dati di tabella 2.1 ed li utilizza per scrivere due archivi SAS; uno relativo alle persone di sesso femminile e l'altro alle persone di sesso maschile.
DATA FEMMINE MASCHI; INPUT NOME $ COGNOME $ NATO_IL $ SESSO $ REDDITO FIGLI TITOLO; IF SESSO='F' THEN OUTPUT FEMMINE; ELSE OUTPUT MASCHI; CARDS; Mario Aloia 16/10/52 M 32000000 1 1 Marco Bianchi 15/08/50 M 26000000 0 2 Elia Biorci 15/08/50 M 27000000 1 1 Walter Chiari 12/03/42 M 95000000 0 4 Guido Fusi 26/02/54 M 35000000 3 2 Ada Mori 27/05/57 F 40000000 0 1 Anna Neri 22/11/60 F 80000000 5 0 Gina Rossi 11/05/56 F 25000000 2 . Licia Saba 15/08/65 F 36000000 2 3 Enzo Verdi 12/08/62 M 35000000 1 1 Guido Zini 05/08/46 M . 1 1 RUN; PROC PRINT DATA=MASCHI; PROC PRINT DATA=FEMMINE; RUN;

Figura 5.11: Costituzione degli archivi di partenza per gli esempi Le due PROC PRINT produrranno le stampe di figura 5.12 e 5.13:
OBS NOME 1 2 3 4 5 6 7 Mario Marco Eia Walter Guido Enzo Guido COGNOME Aloia Bianchi Biorci Chiari Fusi Verdi Zini NATO_IL SESSO REDDITO 16/10/52 15/08/50 15/08/50 12/03/42 26/02/54 12/08/62 05/08/46 M M M M M M M 32000000 26000000 27000000 95000000 35000000 35000000 . FIGLI 1 0 1 0 3 1 1 TITOLO 1 2 1 4 2 1 1

Figura 5.12: Archivio "MASCHI"

181

OBS NOME 1 2 3 4 Ada Anna Gina Licia

COGNOME Mori Neri Rossi Saba

NATO_IL 27/05/57 22/11/60 11/05/56 15/08/65

SESSO F F F F

REDDITO 40000000 80000000 25000000 36000000

FIGLI TITOLO 0 5 2 2 1 0 . 3

Figura 5.13: Archivio "FEMMINE" Quando si presenta la necessit di riunire pi archivi SAS in uno solo, possiamo fare uso delle possibilit offerte dalla dichiarazione SET. Esempio:
DATA ENTRAMBI; SET FEMMINE MASCHI; PROC PRINT; RUN;

La dichiarazione SET permette di specificare pi file SAS (fino a 50); questo non rappresenta un limite reale in quanto nella pratica non capita mai di dover leggere cos tanti archivi con un'unica dichiarazione. Nel caso di lettura da archivi multipli vengono lette tutte le osservazioni del primo, poi tutte quelle del secondo, ecc.. Il passo PROC PRINT scritto sopra produce la stampa mostrato in figura 5.14.
OBS NOME 1 2 3 4 5 6 7 8 9 10 11 Ada Anna Gina Licia Mario Marco Eia Walter Guido Enzo Guido COGNOME Mori Neri Rossi Saba Aloia Bianchi Biorci Chiari Fusi Verdi Zini NATO_IL 27/05/57 22/11/60 11/05/56 15/08/65 16/10/52 15/08/50 15/08/50 12/03/42 26/02/54 12/08/62 05/08/46 SESSO REDDITO F F F F M M M M M M M 40000000 80000000 25000000 36000000 32000000 26000000 27000000 95000000 35000000 35000000 . FIGLI 0 5 2 2 1 0 1 0 3 1 1 TITOLO 1 0 . 3 1 2 1 4 2 1 1

Figura 5.14: Archivio "ENTRAMBI" Come si pu notare, le osservazioni dell'archivio di figura 5.14 non hanno lo stesso ordine dei dati di figura 5.11 da cui siamo partiti. Le osservazioni, cio, non sono ordinate alfabeticamente per cognome, ma si trovano prima quelle relative alle femmine e poi quelle relative ai maschi. Se volessimo produrre in uscita l'archivio ENTRAMBI ordinato alfabeticamente, potremmo usare la SET in 182

congiunzione con la dichiarazione BY. Con la BY infatti, si pu specificare una o pi variabili che verranno utilizzate come chiave di lettura. Il programma risulta quindi:
DATA ENTRAMBI; SET FEMMINE MASCHI; BY COGNOME; PROC PRINT; RUN;

Anche nel passo di DATA, esattamente come nelle procedure, l'utilizzo della dichiarazione BY permesso solo se gli archivi di partenza sono ordinati relativamente alla variabile indicata. Quando si usa la dichiarazione BY viene effettuato un confronto, prima di ogni lettura, tra le osservazioni da leggere in tutti gli archivi di ingresso specificati nella SET e viene scelta l'osservazione che ha il valore della variabile indicata nella BY pi "basso". La dichiarazione BY pu indicare anche pi di una variabile; in questo caso l'ordine determinato dal valore della prima variabile della lista; in condizioni di uguaglianza della prima variabile che forma la chiave di lettura, viene preso in considerazione il valore della seconda variabile, ecc. La stampa dell'archivio "ENTRAMBI" mostrata in figura 5.15.
OBS NOME 1 2 3 4 5 6 7 8 9 10 11 Mario Marco Eia Walter Guido Ada Anna Gina Licia Enzo Guido COGNOME Aloia Bianchi Biorci Chiari Fusi Mori Neri Rossi Saba Verdi Zini NATO_IL 16/10/52 15/08/50 15/08/50 12/03/42 26/02/54 27/05/57 22/11/60 11/05/56 15/08/65 12/08/62 05/08/46 SESSO M M M M M F F F F M M REDDITO 32000000 26000000 27000000 95000000 35000000 40000000 80000000 25000000 36000000 35000000 . FIGLI TITOLO 1 0 1 0 3 0 5 2 2 1 1 1 2 1 4 2 1 0 . 3 1 1

Figura 5.15: Nuova versione dell'archivio "ENTRAMBI"

5.8. Lettura di archivi SAS con la dichiarazione MERGE


Riscriviamo l'esempio mostrato in figura 5.11 al fine di creare due archivi: uno conterr i dati anagrafici (ANAGRAFE) mentre l'altro conterr ulteriori dati dei nostri personaggi (NOTIZIE).

183

Utilizzeremo il seguente programma formato da un passo di DATA che crea gli archivi e due passi di PROC per la stampa degli archivi cos ottenuti.
DATA ANAGRAFE (KEEP=NOME COGNOME NATO_IL SESSO TITOLO) NOTIZIE (KEEP=COGNOME REDDITO FIGLI); INPUT NOME $ COGNOME $ NATO_IL $ SESSO $ REDDITO FIGLI TITOLO; CARDS; Mario Aloia 16/10/52 M 32000000 1 1 Marco Bianchi 15/08/50 M 26000000 0 2 Elia Biorci 15/08/50 M 27000000 1 1 Walter Chiari 12/03/42 M 95000000 0 4 Guido Fusi 26/02/54 M 35000000 3 2 Ada Mori 27/05/57 F 40000000 0 1 Anna Neri 22/11/60 F 80000000 5 0 Gina Rossi 11/05/56 F 25000000 2 . Licia Saba 15/08/65 F 36000000 2 3 Enzo Verdi 12/08/62 M 35000000 1 1 Guido Zini 05/08/46 M . 1 1 RUN; PROC PRINT DATA=ANAGRAFE; PROC PRINT DATA=NOTIZIE; RUN;

Gli archivi risultanti dal passo precedente sono quelli mostrati in figura 5.16 e figura 5.17.

OBS 1 2 3 4 5 6 7 8 9 10 11

NOME Mario Marco Eia Walter Guido Ada Anna Gina Licia Enzo Guido

COGNOME Aloia Bianchi Biorci Chiari Fusi Mori Neri Rossi Saba Verdi Zini

NATO_IL 16/10/52 15/08/50 15/08/50 12/03/42 26/02/54 27/05/57 22/11/60 11/05/56 15/08/65 12/08/62 05/08/46

SESSO M M M M M F F F F M M

TITOLO 1 2 1 4 2 1 0 . 3 1 1

Figura 5.16: Archivio "ANAGRAFE" Gli archivi ANAGRAFE e NOTIZIE hanno lo stesso numero di osservazioni, ma un diverso numero di variabili. Solo la variabile COGNOME presente in ambedue gli archivi. Se si volessero ricondurre i due archivi di figure 5.16 e 5.17 ad un unico archivio potremmo sfruttare le possibilit della MERHGE con il seguente programma:

184

DATA UNIONE; MERGE ANAGRAFE NOTIZIE; RUN;

OBS 1 2 3 4 5 6 7 8 9 10 11

COGNOME Aloia Bianchi Biorci Chiari Fusi Mori Neri Rossi Saba Verdi Zini

REDDITO 32000000 26000000 27000000 95000000 35000000 40000000 80000000 25000000 36000000 35000000 .

FIGLI 1 0 1 0 3 0 5 2 2 1 1

Figura 5.17: Archivio "NOTIZIE" Una stampa dell'archivio UNIONE mostrata in figura 5.18; se non teniamo conto dell'ordine delle variabili, esso si presenta uguale a quello mostrato in figura 5.15.
OBS NOME 1 2 3 4 5 6 7 8 9 10 11 Mario Marco Eia Walter Guido Ada Anna Gina Licia Enzo Guido COGNOME Aloia Bianchi Biorci Chiari Fusi Mori Neri Rossi Saba Verdi Zini NATO_IL 16/10/52 15/08/50 15/08/50 12/03/42 26/02/54 27/05/57 22/11/60 11/05/56 15/08/65 12/08/62 05/08/46 SESSO TITOLO M M M M M F F F F M M 1 2 1 4 2 1 0 . 3 1 1 REDDITO FIGLI 1 0 1 0 3 0 5 2 2 1 1

32000000 26000000 27000000 95000000 35000000 40000000 80000000 25000000 36000000 35000000 .

Figura 5.18: Archivio "UNIONE" La dichiarazione MERGE, ogni volta che viene eseguita, preleva tutti i valori dell'osservazione corrente e li porta nel PDV. Questa azione ripetuta per ogni archivio elencato nella dichiarazione "MERGE". La prima osservazione prodotta quindi composta con l'apporto dei dati appartenenti alle prime osservazioni di tutti gli archivi in lettura, la seconda composta con i dati di tutte le seconde osservazioni, ecc. Da quanto detto risulta chiaro che, analogamente a quanto avviene quando si usa la dichiarazione SET, il PDV viene fatto in modo da comprendere tutte le variabili che si trovano negli archivi in ingresso.

185

Anche per la dichiarazione MERGE, come per la SET, il numero degli archivi deve potr essere al massimo 50. La sintassi della dichiarazione : MERGE <archivioSAS_1 > <archivioSAS_2> ... <archivioSAS_n>; dove n non deve superare 50. Consideriamo ora un altro esempio. Immaginiamo che un folletto maligno ci abbia modificato gli archivi di figure 5.16 e 5.17, facendoli risultare come mostrato nelle figure 5.19 e 5.20.
OBS 1 2 3 4 5 6 7 8 9 10 11 NOME Mario Marco Eia Walter Guido Ada Anna Gina Licia Enzo Guido COGNOME Aloia Bianchi Biorci Chiari Fusi Mori Neri Rossi Saba Verdi Zini NATO_IL 16/10/52 15/08/50 15/08/50 12/03/42 26/02/54 27/05/57 22/11/60 11/05/56 15/08/65 12/08/62 05/08/46 SESSO M M M M M F F F F M M TITOLO 1 2 1 4 2 1 0 . 3 1 1

Figura 5.19 : Archivio ANAGRAFE modificato


OBS 1 2 3 4 5 6 7 8 9 10 COGNOME Aloia Bianchi Biorci Chiari Fusi Grigi Neri Saba Verdi Zini REDDITO 32000000 26000000 27000000 95000000 35000000 40000000 80000000 36000000 35000000 . FIGLI 1 2 1 0 3 0 5 2 1 1

Figura 5.20: Archivio NOTIZIE modificato Utilizzando il programma precedente (riportato per comodit di seguito), senza apporre nessuna modifica, otteniamo un archivio che non corrisponde a quanto vogliamo.
DATA ERRATO; MERGE ANAGRAFE NOTIZIE; PROC PRINT; RUN;

Componendo infatti dati provenienti dai due archivi con l'unico criterio dell'ordine delle osservazioni otteniamo un archivio che, come mostrato in figura 5.21, riporta informazioni mescolate in modo non corretto. 186

Ogni esecuzione della dichiarazione MERGE porta nel PDV le variabili di tutte le osservazioni corrispondenti (in base all'ordine di posizione) degli archivi in ingresso.
OBS NOME 1 2 3 4 5 6 7 8 9 10 11 Mario Marco Eia Walter Guido Ada Anna Gina Licia Enzo Guido COGNOME Aloia Bianchi Biorci Chiari Fusi Grigi Neri Saba Verdi Zini Zini NATO_IL SESSO TITOLO 16/10/52 15/08/50 15/08/50 12/03/42 26/02/54 27/05/57 22/11/60 11/05/56 15/08/65 12/08/62 05/08/46 M M M M M F F F F M M 1 0 1 4 2 1 0 . 3 1 1 REDDITO 32000000 26000000 27000000 95000000 35000000 40000000 80000000 36000000 35000000 . . FIGLI 1 2 1 0 3 0 5 2 1 1 .

Figura 5.21: Archivio risultante da un errato uso della MERGE Evidentemente il risultato ottenuto in figura 5.21 non pu essere considerato soddisfacente. Possiamo ricorrere anche in questo caso all'uso della dichiarazione BY che ci permette di stabilire una chiave di controllo. In questo modo, prima di effettuare la lettura, viene effettuato il controllo di corrispondenza della chiave. I campi del PDV relativi a variabili non riempite durante una lettura vengono lasciati vuoti. Se la dichiarazione MERGE indica pi di due archivi di lettura, si procede con tutti gli altri archivi in modo analogo. Anche in questo caso la chiave indicata dalla dichiarazione BY costituita dal valore di una o pi variabili e gli archivi di partenza devono essere ordinati per quelle variabili . Utilizzando la dichiarazione BY otterremo un archivio ordinato secondo i valori delle variabili che costituiscono la chiave. Aggiungendo la dichiarazione BY all'esempio precedente otterremo i seguente programma:
DATA CORRETTO; MERGE ANAGRAFE NOTIZIE; BY COGNOME; PROC PRINT; RUN;

Eseguendo il programma riportato sopra sugli archivi mostrati nelle figure 5.19 e 5.20 otterremo l'archivio mostrato in figura 5.22. Negli esempi precedenti la chiave utilizzata dalla dichiarazione BY univoca: esiste cio solo una osservazione per ogni archivio che ha la stessa chiave.

187

OBS NOME 1 2 3 4 5 6 7 8 9 10 11 12 Mario Marco Eia Walter Guido Ada Anna Gina Licia Enzo Guido

COGNOME Aloia Bianchi Biorci Chiari Fusi Grigi Mori Neri Rossi Saba Verdi Zini

NATO_IL SESSO 16/10/52 15/08/50 15/08/50 12/03/42 26/02/54 27/05/57 22/11/60 11/05/56 15/08/65 12/08/62 05/08/46 M M M M M F F F F M M

TITOLO 1 2 1 4 2 . 1 0 . 3 1 1

REDDITO FIGLI 32000000 26000000 27000000 95000000 35000000 40000000 . 80000000 . 36000000 35000000 . 1 2 1 0 3 0 . 5 . 2 1 1

Figura 5.22: Archivio risultante da un corretto uso della MERGE Esaminiamo invece cosa succede se, negli archivi presi in considerazione, una chiave risulta ripetuta in pi osservazioni di uno stesso archivio. Immaginiamo di avere un archivio anagrafico dei clienti (CLIENTI) di un albergo e un secondo archivio che riporta le prenotazioni effettuate dai clienti (PRENOTAZ).
OBS 1 2 3 4 5 COGNOME Bianchi Neri Rossi Verdi Zini CITTA ROMA SIENA PISA MILANO BARI

Figura 5.23: Anagrafico Clienti


OBS 1 2 3 4 5 COGNOME Bianchi Neri Rossi Rossi Verdi DAL 15/07/88 10/07/88 01/07/88 11/07/88 25/07/88 AL 20/07/88 12/07/88 03/07/88 12/07/88 27/07/88

Figura 5.24: Prenotazione dei clienti di un albergo Se vogliamo riunire le informazioni anagrafiche del cliente e quelle relative alle prenotazioni possiamo scrivere:
DATA PRENOT; MERGE CLIENTI PRENOTAZ; BY COGNOME; PROC PRINT; RUN;

188

La PROC PRINT produce la seguente stampa:


OBS 1 2 3 4 5 6 COGNOME Bianchi Neri Rossi Rossi Verdi Zini CITTA ROMA SIENA PISA PISA MILANO BARI DAL 15/07/88 10/07/88 01/07/88 11/07/88 25/07/88 AL 20/07/88 12/07/88 03/07/88 12/07/88 27/07/88

Figura 5.25: Archivio "PRENOT" Il risultato a prima vista del tutto consono alle aspettative, ma se si segue il flusso del programma, ci accorgiamo che qualcosa di "strano" avvenuto. Infatti dopo che il sistema ha letto l'osservazione relativa al sig. ROSSI del primo archivio e la prima osservazione relativa al sig. ROSSI del secondo archivio e dopo che ha scritto il PDV nell'archivio di uscita, non stata fatta l'inizializzazione a valore mancante del PDV. Infatti nell'osservazione successiva troviamo ancora il contenuto della variabile CITTA impostato nel ciclo precedente. In generale si pu affermare che il sistema non esegue la inizializzazione a valore mancante del PDV quando il contenuto della variabile indicata come chiave (COGNOME nel nostro caso) non risulta modificato nella successiva osservazione. Si pu considerare che in questi casi il sistema SAS inserisca dinamicamente una dichiarazione RETAIN.

5.9.

I parametri END, FIRST., LAST. E IN

Al fine di permettere un completo controllo delle dichiarazioni di lettura di archivi SAS, il sistema ci mette a disposizione variabili che indicano particolari condizioni quali ad esempio: il raggiungimento della fine di un archivio, il passaggio da una chiave ad un'altra (detta in gergo "rottura di codice") e la provenienza dell'informazione quando leggiamo, con una sola dichiarazione, da pi di un archivio. Con il parametro END=" possiamo definire una variabile che vale 1 se l'osservazione letta l'ultima degli archivi di ingresso. Chi utilizza altri linguaggi di programmazione (COBOL, FORTRAN, PL/I ecc.) deve fare attenzione al fatto che il sistema SAS segnala la fine dell'archivio di ingresso in anticipo rispetto alla maggioranza degli altri linguaggi. Mentre questi segnalano infatti la fine dell'archivio quando si tenta di eseguire la lettura di un record 189

successivo all'ultimo, il sistema SAS segnala la fine dell'archivio quando stata letta l'ultima osservazione. Se noi ignoriamo la segnalazione cercando di leggere ulteriormente, il sistema conclude il passo corrente passando all'eventuale passo successivo o terminando il programma. Il parametro "END= pu essere specificato solo una volta nella dichiarazione di lettura di archivi SAS (SET, MERGE o UPDATE), indipendentemente dal numero di archivi in ingresso, nel seguente modo: SET DATI1 DATI2 END=EOF ; dove DATI1 e DATI2 sono ipotetici archivi di ingresso ed EOF la variabile scelta per segnalare quando stata letta l'ultima osservazione. La variabile definita con il parametro "END=" risiede nel PDV e si pu utilizzare normalmente all'interno del passo di DATA, ma non viene riportata nell'archivio di uscita come se fosse stata inserita automaticamente una dichiarazione DROP per quella variabile. Il parametro IN= pu essere specificato nella dichiarazione di lettura (SET, MERGE o UPDATE), associato a ciascun archivio di ingresso, nel seguente modo: MERGE DATI1 (IN=A) DATI2 (IN=B); dove DATI1 e DATI2 sono due ipotetici archivi di ingresso ed A e B sono le variabili scelte per sapere da quale archivio stata prelevata l'osservazione corrente. Se i dati provengono dall'archivio DATI1, risulter A=1 (vero) e B=0 (falso); se al i dati provengono dall'archivio DATI2, risulter A=0 (falso) e B=1 (vero); se infine provengono da entrambi gli archivi risulter A=1 (vero) e B=1 (vero). Le variabili definite con il parametro IN= risiedono nel PDV e si possono utilizzare normalmente, ma non vengono riportate nell'archivio di uscita come se fosse stata inserita automaticamente una dichiarazione DROP per tali variabili. I qualificatori "FIRST." e "LAST.", uniti al nome di una variabile che funge da chiave di lettura, vengono inseriti automaticamente dal sistema SAS per ciascuna variabile specificata dopo una dichiarazione BY; essi definiscono variabili che segnalano la prima o l'ultima occorrenza di una chiave. Anche tali variabili valgono 1 quando si verifica l'evento da segnalare e valgono 0 quando quest'ultimo non verificato. Tali variabili automatiche, analogamente alle altre viste in precedenza, non vengono trascritte nell'archivio di uscita.

190

L'esempio che segue mette in evidenza i valori ottenuti con l'uso dei parametri "END=", "IN=", "FIRST." e "LAST.". Siano dati i due archivi SAS di nome FILESAS1 e FILESAS2 mostrati di seguito.
FILESAS1
OBS CLIENTE IMPORTO 1 2 3 4 5 6 BIANCHI BIANCHI NERI ROSSI ROSSI VERDI 10000 30000 50000 20000 5000 80000 1 2 3 4

FILESAS2
OBS CLIENTE IMPORTO BIANCHI BIANCHI VERDI VERDI 50000 6000 60000 10000

Con il seguente programma si evidenziano tutte le caratteristiche dei parametri "IN=", "FIRST.", "LAST." e "END=":
DATA; SET FILESAS1 (IN=F1) FILESAS2 (IN=F2) END=F; BY CLIENTE; IN_F1=F1; IN_F2=F2; PRIMO_C=FIRST.CLIENTE; ULTIMO_C=LAST.CLIENTE; FINE=F; PROC PRINT; RUN;

Otteniamo la stampa:
OBS CLIENTE IMPORTO IN_F1 IN_F2 PRIMO_C ULTIMO_C FINE 1 2 3 4 5 6 7 8 9 10 BIANCHI BIANCHI BIANCHI BIANCHI NERI ROSSI ROSSI VERDI VERDI VERDI 10000 30000 50000 6000 50000 20000 5000 80000 60000 10000 1 1 0 0 1 1 1 1 0 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 1 1 0 1 0 0 0 0 0 1 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 1

Le variabili definite da parametri speciali (F1, F2, F, FIRST.CLIENTE, LAST.CLIENTE) non sono riportate dal sistema SAS nell'archivio di uscita e, per conoscerne i valori in ciascuna osservazione, sono stati assegnati a normali variabili SAS i valori delle variabili definite con i parametri speciali. Queste ultime variabili sono presenti nell'archivio di uscita e quindi nella stampa finale. Possiamo controllare che il valore di IN_F1 1 quando l'osservazione proviene dal primo archivio, mentre 0 quando non proviene da questo archivio. La variabile IN_F2 ha i valori esattamente opposti a quelli di IN_F1. Cos PRIMO_C diviene 1 ogni volta che un cliente compare per la prima volta, mentre 191

ULTIMO_C diviene 1 solo l'ultima volta che compare un cliente. La variabile FINE diventa 1 solo dopo che l'ultima osservazione stata letta.

5.10.

La dichiarazione UPDATE

La dichiarazione UPDATE, a differenza della SET e della MERGE, permette di leggere solo due archivi SAS, ed obbliga all'utilizzo della dichiarazione BY. Inoltre non possibile scambiare tra loro gli archivi in lettura che devono essere dati esattamente nel modo indicato nella seguente sintassi: UPDATE <archivio da aggiornamenti>; BY <elenco variabili >; dove: archivio da aggiornare deve avere la chiave di lettura univoca; non devono cio esistere due osservazioni che hanno lo stesso valore delle variabili indicate dalla dichiarazione BY. archivio aggiornamenti pu contenere pi osservazioni per ogni chiave o nessuna osservazione se non ci sono aggiornamenti da fare. Le variabili dell'archivio aggiornamenti che hanno valore vuoto non provocano nessun aggiornamento. elenco variabili l'elenco delle variabili che verranno utilizzate dal sistema SAS come chiave di controllo e quindi devono essere presenti in ambedue gli archivi. Anche in questo caso cerchiamo di spiegare con un esempio il meccanismo utilizzato dalla UPDATE per eseguire l'aggiornamento. Consideriamo di voler modificare il nostro archivio ENTRAMBI di figura 5.15 con gli aggiornamenti riportati in figura 5.26 (archivio AGGIORN). Un possibile programma di aggiornamento che utilizzi la dichiarazione UPDATE il seguente:
DATA NUOVO; UPDATE ENTRAMBI AGGIORN; BY COGNOME; RUN; PROC PRINT; RUN;

aggiornare>

<archivio

192

Gli aggiornamenti da apportare all'archivio ENTRAMBI sono:


OBS NOME 1 2 3 4 4 5 COGNOME NATO_IL Aloia Neri Rossi Saba Zini Zoni SESSO REDDITO . . 28000000 40000000 30000000 22000000 FIGLI 2 . . 3 . 0 TITOLO . 2 3 . . 4

23/11/60 15/09/65 12/08/68 F

Rita

Figura 5.26: Archivio "AGGIORN" contenente gli aggiornamenti Nell'archivio AGGIORN sono stati riportati quei valori che devono modificare i corrispondenti nell'archivio ENTRAMBI, mentre i valori che non devono provocare variazioni sono stati lasciati vuoti. L'osservazione 5 riporta i valori di una nuova osservazione che sar aggiunta all'archivio. Si riporta di seguito la stampa dell'archivio creato con il nome NUOVO.
OBS 1 2 3 4 5 6 7 8 9 10 11 12 NOME COGNOME Aloia Bianchi Biorci Chiari Fusi Mori Neri Rossi Saba Verdi Zini Zoni NATO_IL SESSO 16/10/52 15/08/50 15/08/50 12/03/42 26/02/54 27/05/57 23/11/60 11/05/56 15/09/65 12/08/62 05/08/46 12/08/68 M M M M M F F F F M M F REDDITO 32000000 26000000 27000000 95000000 35000000 40000000 80000000 28000000 40000000 35000000 30000000 22000000 FIGLI 2 0 1 0 3 0 5 2 3 1 1 0 TITOLO 1 2 1 4 2 1 2 3 3 1 1 4 Mario Marco Eia Walter Guido Ada Anna Gina Licia Enzo Guido Rita

Figura 5.27: Archivio di nome "NUOVO"

5.11. Esempi di utilizzo delle dichiarazioni MERGE ed UPDATE


La dichiarazione MRGE ha innumerevoli applicazioni nella pratica; cercheremo in questa sede di illustrare con esempi alcuni tra i casi che ricorrono pi spesso. Una mensa aziendale registra ogni giorno la spesa effettuata dai dipendenti. A fine mese l'ufficio contabile della mensa invia una richiesta di pagamento ai suoi clienti. Nell'ufficio contabile viene tenuto un archivio di tutti i dipendenti chiamato "CLIENTI" ed un secondo archivio dove sono registrate le spese effettuate chiamato "SPESE". 193

OBS CLIENTE MATRICOL INDIRIZ 1 2 3 4 BIANCHI NERI ROSSI VERDI 54768 54344 57657 65335 Via Via Via Via Larga, 8 Stretta, 1 Buia, 3 Corta, 5

CITTA Asciano Poggibonsi Castellina Faggeta

Figura 5.28: Archivio di nome "CLIENTI" contenente i dati anagrafici

OBS CLIENTE 1 2 3 4 5 BIANCHI BIANCHI NERI NERI VERDI

DATA 15/09/88 16/09/88 15/09/88 16/09/88 15/09/88

IMPORTO 8500 8800 9000 7850 10000

Figura 5.29: Archivio di nome "SPESE" Con un semplice passo di DATA possibile ottenere un archivio che contiene le osservazioni relative a tutti gli impiegati complete con le spese e gli indirizzi:
DATA FATTURE; DROP MATRICOL; MERGE CLIENTI SPESE; BY CLIENTE; PROC PRINT; RUN;

Non stata registrata la matricola perch in questa fase non necessaria. La PROC PRINT produce quindi la stampa riportata in figura 5.30. Gi il risultato ottenuto, se stampato in modo consono, pu rappresentare un primo tipo di estratto conto.
OBS CLIENTE INDIRIZ 1 2 3 4 5 6 BIANCHI BIANCHI NERI NERI ROSSI VERDI Via Via Via Via Via Via CITTA DATA IMPORTO 8500 8800 9000 7850 . 10000

Larga, 8 Asciano 15/09/88 Larga, 8 Asciano 16/09/88 Stretta, 1 Poggibonsi 15/09/88 Stretta, 1 Poggibonsi 16/09/88 Buia, 3 Castellina Corta, 5 Faggeta 15/09/88

Figura 5.30: Archivio di nome "FATTURE"

194

Il seguente programma potrebbe produrre la prima bozza dell'estratto:

PROC PRINT DATA=FATTURE; VAR DATA IMPORTO; BY CLIENTE INDIRIZ CITTA; ID CLIENTE INDIRIZ CITTA; SUM IMPORTO; SUMBY CLIENTE; RUN;

Se al passo sopra riportato si aggiunge anche la dichiarazione PAGEBY potremmo avere una stampa gi suddivisa da consegnare ai clienti.
CLIENTE Bianchi -------Bianchi Neri -------Neri Rossi Verdi Via Buia, 3 Via Corta, 5 Castellina Faggeta 15/09/88 Via Stretta, 1 Poggibonsi 15/09/88 16/09/88 INDIRIZ Via Larga, 8 CITTA Asciano DATA 15/09/88 16/09/88 IMPORTO 8500 8800 -----------17300 9000 7850 -----------16850 . 10000 ============ 44150

Rimangono per le pagine dedicate a quei clienti che non hanno spese nel periodo esaminato. Al programma che crea l'archivio FATTURE potrebbe essere inserito il controllo che elimina le osservazioni che non hanno la relativa spesa. Nel programma che segue, la variabile SP vale 0 se l'osservazione attuale non formata con il contributo dell'archivio SPESE. La dichiarazione IF subsetting provvede a eliminare la scrittura delle osservazioni indesiderate.
DATA FATTURE1; DROP MATRICOL; MERGE CLIENTI SPESE (IN=SP); BY CLIENTE; IF SP=1; /* ovvero IF SP=0 THEN DELETE */ RUN; PROC PRINT; RUN;

Il risultato della PROC PRINT mostrato in figura 5.31. 195

OBS CLIENTE 1 2 3 4 5 BIANCHI BIANCHI NERI NERI VERDI

INDIRIZ Via Via Via Via Via

CITTA

DATA

IMPORTO 8500 8800 9000 7850 10000

Larga, 8 Asciano 15/09/88 Larga, 8 Asciano 16/09/88 Stretta, 1 Poggibonsi 15/09/88 Stretta, 1 Poggibonsi 16/09/88 Corta, 5 Faggeta 15/09/88

Figura 5.31: Archivio "FATTURE1" Un ulteriore miglioramento al programma potrebbe essere quello sommare tutte le spese effettuate da ciascun cliente. Si ricorda che quando si devono eseguire addizioni con valori del PDV provenienti da cicli precedenti, occorre inibire la inizializzazione effettuata automaticamente ad ogni ciclo mediante l'inserimento di una dichiarazione RETAIN. Se per i valori che vogliamo salvare si trovano in una variabile che compare in una dichiarazione SUM, la RETAIN non pi necessaria in quanto viene assunta automaticamente (cfr. paragrafo 2.11). Il programma verrebbe cos modificato:
DATA FATTURE2; DROP MATRICOL IMPORTO DATA; MERGE CLIENTI SPESE (IN=SP); BY CLIENTE; IF SP=1; IF FIRST.CLIENTE=1 /* per ogni nuovo cliente THEN TOTCL=0; /* azzera il totale spese TOTCL+IMPORTO; /*implica RETAIN TOTCL 0 PROC PRINT LABEL; LABEL TOTCL='TOTALE'; RUN;

*/ */ */

La variabile SP vale 0 se all'osservazione attuale contribuisce solamente l'archivio CLIENTI; in altre parole SP vale 1 solo se una persona ha effettuato almeno una spesa durante il mese.
OBS 1 2 3 4 5 CLIENTE BIANCHI BIANCHI NERI NERI VERDI INDIRIZ Via Via Via Via Via Larga, 8 Larga, 8 Stretta, 1 Stretta, 1 Corta, 5 CITTA Asciano Asciano Poggibonsi Poggibonsi Faggeta TOTALE 8500 17300 9000 16850 10000

Figura 5.32: Archivio "FATTURE2" Ancora un miglioramento potrebbe essere ottenuto eliminando le osservazioni che non contengono una somma finale ma solo una somma parziale (intermedia), cio non sono l'ultima osservazione relativa ad un cliente. Si inserisce a tale scopo un test sulla variabile speciale LAST.CLIENTE. 196

DATA FATTURE3; DROP MATRICOL IMPORTO; MERGE CLIENTI SPESE (IN=SP); BY CLIENTE; IF SP=1; IF FIRST.CLIENTE=1 /* per ogni nuovo cliente THEN TOTCL=0; /* azzera il totale spese TOTCL+IMPORTO; /*implica RETAIN TOTCL 0 IF LAST.CLIENTE=1; /*scrivi se cambia cliente RUN; PROC PRINT LABEL; LABEL TOTCL='TOTALE'; RUN;

*/ */ */ */

La IF subsetting finale, interrompe il ciclo del passo DATA quando non stiamo trattando l'ultima osservazione di un cliente; quella cio che contiene il totale generale. Viene impedita cos la scrittura delle osservazioni che contengono somme parziali. Otteniamo:
OBS 1 2 3 CLIENTE BIANCHI NERI VERDI INDIRIZ Via Larga, 8 Via Stretta, 1 Via Corta, 5 CITTA Asciano Poggibonsi Faggeta TOTALE 17300 16850 10000

Figura 5.33: Archivio "FATTURE3" L'utilizzo comune della dichiarazione UPDATE tradizionalmente quello di permettere l'aggiornamento di archivi in modo semplice, ma adatto a molteplici esigenze. Un esempio classico consiste nel tenere aggiornato il valore del saldo in un archivio di tipo contabile. Riprendendo l'esempio degli impiegati che si servono della mensa, immaginiamo di dover conteggiare i versamenti che vengono effettuati e le spese che si accumulano. In un archivio, che chiameremo SALDI, sono registrati i saldi per ogni impiegato ed in un altro, che chiameremo MOVIMEN, sono registrati i movimenti in dare o in avere. Riportiamo di seguito la stampa dei due archivi.
OBS CLIENTE 1 2 3 4 BIANCHI NERI ROSSI VERDI SALDO 20000 -30000 -50750 33000

Figura 5.34: Archivio "SALDI"

197

OBS CLIENTE 1 2 3 4 5 6 7 8 BIANCHI BIANCHI NERI NERI NERI NERI ROSSI VERDI

DARE 10000 0 8000 0 7000 8500 0 8000

AVERE 0 50000 0 50000 0 0 10000 0

Figura 5.35: Archivio "MOVIMEN" Un semplice programma che esegue l'aggiornamento potrebbe essere quello che riportiamo di seguito. Sono state omesse le registrazioni delle variabili DARE e AVERE per poter ottenere un archivio con lo stesso numero di variabili di quello di partenza. Si suppone infatti che l'archivio NUOVO, una volta verificata l'esattezza, degli aggiornamenti effettuati, prender il posto di quello di partenza SALDI.
DATA NUOVO; DROP DARE AVERE; UPDATE SALDI MOVIMEN; BY CLIENTE; SALDO+-DARE; SALDO+AVERE; PROC PRINT; RUN;

Otteniamo cos la seguente stampa:


OBS CLIENTE 1 2 3 4 BIANCHI NERI ROSSI VERDI SALDO 60000 -3500 -40750 25000

Figura 5.36: Archivio "NUOVO" Si noti che, poich nel file MOVIMEN non vi sono nuovi clienti, l'archivio NUOVO, ha tante oservazioni quante ve ne sono nell'archivio da aggiornare SALDI. possibile sovrapporre subito l'archivio aggiornato al vecchio archivio SALDI definendo accanto nella dichiarazione DATA lo stesso nome del primo archivio della dichiarazione UPDATE. Si consiglia per di non fare certi tipi di operazioni in quanto se ci si accorge che l'aggiornamento non corretto, non potremmo ripetere l'operazione in quanto l'archivio originale da cui ripartire non esiste pi. 198

6. Produzione di rapporti

6.1.

Cosa sintende per rapporto

In questo libro, come nella maggior parte della letteratura tecnica, per rapporto si intende una rappresentazione di dati su di un tabulato. In gergo, con il termine report writing, da intendersi l'insieme delle fasi che conducono alla produzione di rapporti. Esistono svariati modi di produrre un rapporto in funzione della forma con cui dovr essere presentato al destinatario (noi stessi, un collega, il responsabile del dipartimento, ecc.) o del livello di dettaglio delle informazioni che saranno presenti su di esso (rapporto di sommario, oppure di dettaglio). La forma (in gergo definita layout) secondo la quale i risultati dell'elaborazione dovranno essere rappresentati in uscita potrebbe essere scelta del produttore del rapporto, oppure essere gi predefinita in virt di particolari esigenze tipografiche (ad esempio: necessit di stampare su moduli prefincati). Il sistema SAS ha notevoli capacit di report writing, mettendo a disposizione procedure standard specializzate nella produzione di rapporti, nonch una serie di strumenti di base, propri del linguaggio SAS, mediante i quali possibile produrre qualsiasi tipo di rapporto senza alcun vincolo. Sebbene alcune di queste procedure siano gi state descritte nel capitolo 3, di seguito esse verranno richiamate ed altre verranno descritte ex-novo. Le principali procedure per la produzione di rapporti sono: 1. PRINT 2. QPRINT 3. FORMS 4. CHART 5. PLOT 6. CALENDAR 7. TABULATE Le procedure 1, 2 e 3 permettono di ottenere delle stampe di dettaglio. Le rimanenti procedure tendono a raggruppare le informazioni e vengono usate per ottenere tabulati di sintesi; in 199

particolare, le procedure 4 e 5 producono delle forme schematiche di rappresentazione grafica dei dati, mentre la 6 e la 7 generano uscite sotto forma di tabelle sinottiche. Particolare attenzione verr posta nella trattazione della PROC TABULATE, non solo per l'interesse e l'utilit di questa procedura, ma anche per la sua oggettiva complessit. Quando si producono rapporti, si cerca di fornire in uscita i risultati in una forma che sia la pi leggibile possibile; per questo, nel contesto delle procedure che verranno descritte successivamente, si far spesso uso di formati di uscita. In seguito si parler di formati, sia di quelli "preconfezionati" gi previsti dal sistema SAS, sia di quelli definibili dall'utente mediante la procedura FORMAT.

6.2.

La procedura PRINT

La PRINT una procedura di semplice uso per produrre liste in cui ciascuna colonna rappresenta i valori assunti da una variabile di un archivio SAS. Detta procedura, ampiamente illustrata nel capitolo 3, automaticamente centra nella pagina i valori in stampa regolandone la spaziatura orizzontale e verticale e non permette la definizione delle colonne o delle righe di inizio a partire dalle quali stampare i dati. Le personalizzazioni consentite dalla PROC PRINT sono le seguenti: la stampa delle sole variabili desiderate, eventualmente nell'ordine indicato dalla dichiarazione VAR; la stampa per gruppi, secondo quanto specificato della dichiarazione BY; la stampa formattata di dati, mediante l'associazione variabile-formato operata tramite la dichiarazione FORMAT; la sostituzione del nome delle variabili con una etichetta assegnata, tramite la dichiarazione LABEL, nelle intestazioni delle colonne; la rappresentazione delle etichette su pi righe mediante l'opzione SPLIT; la doppia spaziatura delle righe di stampa mediante l'opzione DOUBLE; l'inserimento di titoli in testa o a pi di pagina, rispettivamente mediante le dichiarazioni TITLE e FOOTNOTE;

200

la totalizzazione a fine rapporto di valori stampati in colonne assegnate a variabili numeriche, mediante la dichiarazione SUM; l'uso congiunto delle dichiarazioni ID e BY per eliminare la stampa di informazioni ridondanti; la possibilit di ottenere totalizzazioni parziali mediante l'uso congiunto delle dichiarazioni BY e SUM; il controllo del salto a pagina nuova mediante la dichiarazione PAGEBY. Oltre a quanto elencato, la PROC PRINT non offre altro e non pertanto adatta a produrre rapporti da stampare su moduli prefincati (a meno di accorgimenti molto complicati e noiosi quali, ad esempio, la definizioni di variabili di comodo contenenti spazi da usarsi come colonne di riempimento, ecc.). Per poter risolvere il suddetto problema dobbiamo ricorrere all'uso di altre procedure o, meglio, a strumenti di programmazione, tipici del passo di DATA, come le dichiarazioni FILE e PUT, che analizzeremo in dettaglio nel paragrafo 6.10.

6.3.

I formati di uscita

In generale per formato di output assegnato ad una variabile si intende la rappresentazione mediante la quale i valori di detta variabile saranno prodotti in uscita. Ad esempio, se si desidera stampare i valori di una variabile numerica in modo tale che il numero di cifre alla destra del punto decimale sia tre, occorrer specificarlo esplicitamente mediante una associazione che leghi la variabile al formato desiderato. Questo pu essere fatto mediante una dichiarazione FORMAT la cui forma generale : FORMAT variabile(i) <nome del formato.> variabile(i) <nome del formato.> . . . . . ; Si noti che possiamo assegnare un formato desiderato a pi di una variabile e che assolutamente necessario far seguire immediatamente al nome del formato un carattere "punto" (.). Il sistema SAS mette a disposizione un considerevole numero di formati assegnabili sia a variabili di tipo numerico che non numerico; inoltre vengono forniti utili formati per variabili che rappresentino delle date, dei tempi o un composto di date e tempi. Come gi visto nel capitolo 4, il sistema SAS tratta date, tempi e composti data e tempo, come numeri; in particolare, una data memorizzata in un archivio SAS come un intero, positivo o negativo, che rappresenta il numero di giorni che la separa (in avanti o indietro) da una data base che, per il sistema SAS, il 1/1/1960. Un tempo memorizzato da un numero intero positivo rappresentante i 201

secondi fra quel temp e la mezzanotte. Nome formato c. $c. c.d BESTc. Descrizione c-Ampiezza della notazione (in caratteri) numerica standard 1-32 non numerica standard 1-200 num. standard con decimali 1-32 il SAS sceglie la migliore notazione possibile 1-32 $CHARc. non numerica con bianchi 1-200 DATEc. data nella forma ddMMMyy dd=giorno del mese (1-31) MMM=primi tre caratteri del mese (in inglese) yy=cifre dell'anno (2 o 4) 5-9 DDMMYYc. data nella forma: DD=giorno del mese (1-31) MM=mese (1-12) YY=anno 2-8 Ec. scientifica 7-32 FRACTc. frazionaria 4-32 HEXc. numerica esadecimale 1-16 IBc.d binaria intera 1-8 PDc.d decimale packed 1-16 TIMEc. tempo della forma: hh:mm:ss.cc hh=ore, mm=minuti ss=secondi cc=centesimi di secondo 2-20 WORDSc. i numeri vengono espressi a parole (in inglese) 5-200 Zc.d verranno stampati anche gli zero non significativi 1-32 ZDc.d decimale con zonatura 1-16 YYQc. data nella forma: YY=anno Q=numero di trimestre(1-4) 4-6 Allineamento destra sinistra destra destra sinistra

-----

----destra destra sinistra sinistra sinistra

----sinistra destra sinistra

----

Figura 6.1: Lista parziale dei formati previsti dal sistema SAS Un composto, data e tempo, memorizzato come un intero, positivo o negativo, rappresentante il numero di secondi che intercorrono tra la data-tempo in questione e la mezzanotte del 1/1/60. La figura 6.1 mostra una lista di formati con una brevissima descrizione del contesto nel quale essi sono utilizzabili; dato il notevole numero di formati messi a disposizione dal sistema SAS, si rimanda il lettore alla lettura del testo SAS User's Guide: Basics per 202

dettagli ed esempi circa il loro uso. In aggiunta, l'utente pu definirsi dei propri formati mediante la procedura FORMAT che verr descritta in seguito. L'uso di questa procedura permette anche di definire delle classi di valori che le variabili SAS possono assumere, permettendo cos di effettuare, ad esempio, delle discretizzazioni di variabili numeriche continue quali: et, altezze, stipendi, ecc.. L'uso di una dichiarazione FORMAT all'interno di un passo di DATA permette una assegnazione variabile-formato permanente; per rimuovere successivamente detta assegnazione, che riportata nella parte descrittiva dell'archivio SAS, si pu fare uso della procedura DATASETS. Un altro metodo pu essere quello di utilizzare, in un passo di DATA, una dichiarazione FORMAT nella quale presente il nome della variabile da cui si intende rimuovere il formato non seguita da alcun formato.

6.4.

La procedura FORMAT

La procedura FORMAT permette la creazione di due tipi diversi di formato, direttamente da parte dell'utente. La forma generale di richiamo della procedura la seguente:
PROC FORMAT [opzioni]; VALUE <nome del formato> [(opzioni)] intervallo_1 = 'valore_1' ....... = ....... intervallo_n = 'valore_n'; PICTURE <nome del formato> [(opzioni)] intervallo_1= 'maschera_1 '[(opzioni)] ..... = ..... intervallo_n='maschera_n' [(opzioni)];

Ciascuna dichiarazione che segue la PROC definisce un formato e nel contesto di una singola chiamata possono trovar luogo pi dichiarazioni VALUE e/o PICTURE. Sia nella dichiarazione VALUE che nella PICTURE, il nome del formato deve essere un nome SAS valido, non deve terminare con un numero e non deve essere uguale al nome di un formato SAS gi esistente. Occorre fare attenzione che, anche se si contravviene all'ultima regola, il sistema SAS crea comunque un formato avente lo stesso nome di uno gi preconfezionato ma, quando esso verr assegnato ad una variabile, il sistema SAS utilizzer il formato standard e non quello definito dall'utente. Infatti, il sistema SAS effettua la ricerca di un formato per nome, a partire dalla propria libreria di formati e, solo se la ricerca fallisce, esso continua con l'ispezione delle librerie eventualmente definite dall'utente in fase di avvio di una sessione interattiva o mediante le 203

schede di controllo del job inviato per l'esecuzione. I formati definiti mediante la dichiarazione VALUE associano a ciascun valore di una variabile, numerica o non numerica, etichette (label) che sostituiranno in uscita detti valori. Di seguito vengono riportati alcuni esempi di definizioni di formati mediante la dichiarazione VALUE. Si tenga presente che le stringhe racchiuse fra apici possono essere lunghe al massimo 40 caratteri. Esempio:
VALUE DIPARFMT 1 = 'Pubblica Istruzione' 2 = 'Sport e Spettacolo' 3 = 'Sicurezza Sociale' .................. .................. 9 = 'Errore di codifica';

Esempio:
VALUE ETAFMT 0-<13 13-<18 18-60 60<-HIGH OTHER = = = = = 'Bambino' 'Adolescente' 'Adulto' 'Maturo' 'Eta'' errata';

la notazione 0-<13='Bambino' da interpretarsi cos: se il valore dalla variabile a cui stato associato il formato ETAFMT compreso nell'intervallo semi-aperto [0,13), in uscita verr prodotta la stringa 'Bambino'. La notazione 60<-HIGH indica l'intervallo aperto (60, ). Al fine di segnalare in uscita la presenza di valori invalidi, ad esempio, un valore negativo della variabile ETA, nel formato ETAFMT stata prevista una classe speciale OTHER. Nel caso della definizione di un formato da associare ad una variabile non numerica, il nome del formato deve cominciare con un carattere "dollaro" ($). Esempio:
VALUE $RISPFMT 'A' = 'Sono d''accordo totalmente' 'B'-'E' = 'Sono parzialmente d''accordo' 'F' = 'Nutro forti perplessita''' 'L' = 'Sono in totale disaccordo' '*' = 'Non intendo rispondere a questa domanda' OTHER = 'Codice non previsto: correggi';

I formati definiti mediante la dichiarazione PICTURE, rappresentano delle maschere di uscita e sono associabili solo a variabili 204

numeriche. Mediante dette maschere possibile produrre i valori numerici in uscita secondo svariate modalit definibili mediante apposite opzioni; ad esempio possibile: inserire uno o due caratteri di prefisso davanti al numero (opzione PREFIX=); definire un fattore numerico che verr moltiplicato al numero prima che esso sia prodotto in uscita (opzione MULT=); definire un carattere di riempimento che sostituir tutti i caratteri non significativi che precedono la cifra posta pi a sinistra del numero in uscita (opzione FILL=). Le picture sono sequenze di 24 caratteri al massimo nelle quali, ciascun carattere pu essere considerato alternativamente come: carattere-selettore di cifre, oppure carattere-messaggio . I caratteri-selettori sono rappresentati dalle cifre scelte tra 0 a 9 ed indicano le posizioni di uscita riservate a cifre del numero; se, per la costruzione della picture, si utilizza il carattere zero questo comander la visualizzazione del numero senza che gli zero non significativi vengano evidenziati; viceversa se si utilizzano caratteriselettori scelti tra 1 e 9, gli zero non significativi appariranno in uscita. I caratteri-messaggio saranno stampati esattamente nella posizione nella quale essi compaiono, ma occorre ricordare che un carattere- messaggio non pu essere il primo carattere a sinistra di una picture. Di seguito vengono riportati alcuni esempi di definizioni di formati mediante la dichiarazione PICTURE. Esempio:
PICTURE ITALFMT LOW-<0 ='0.000.009,00' (PREFIX='-' MULT=100) 0-HIGH ='0.000.009,00' (MULT=100);

L'uscita dei numeri viene normalmente regolata dallo standard americano secondo il quale il carattere punto (.) funge da separatore tra parte intera e parte decimale del numero, mentre la virgola (,) usata per separare, da destra a sinistra, a gruppi di tre, le cifre della parte intera del numero. Il formato ITALFMT pu essere assegnato ad una variabile numerica per comandare l'adozione dello standard italiano nella stampa del numero (la virgola separa la parte intera da quella decimale e il punto funge da separatore delle cifre della parte intera). Esempio:

205

PICTURE MIGLIAIA 0-HIGH = '000,009K' (MULT=.001);

La tabella seguente mostra in quale modo saranno prodotti in uscita i valori di una variabile alla quale stato assegnato il valore MIGLIAIA.
Valore della variabile 1200 1500 100 10000 10542 1000000 Valore prodotto in uscita 1K 1K 0K 10K 10K 1,000K

Esempio:
PICTURE SUPERO LOW-<-9999 = -9999-<0 = 0-<1E7 = 1E7-HIGH = 'Troppo piccolo'(NOEDIT) '0000' (PREFIX='-') '00,000,009' 'Troppo grande' (NOEDIT);

Il formato SUPERO pu essere utilizzato per controllare che i valori di una variabile numerica rientrino all'interno di determinati intervalli, segnalando con dei messaggi opportuni la presenza di valori fuori intervallo. Infatti nel formato SUPERO, vengono definiti i seguenti intervalli: (-,-9999) [-9999, 0) [0, +10.000.000) [+10.000.000,+ ). I valori che ricadono nel primo e nell'ultimo intervallo verranno evidenziati con una descrizione che segnala l'errore. Per concludere questa breve panoramica sulla procedura FORMAT occorre dire che possibile conservare i formati definiti in un programma in librerie proprie dell'utente, in modo che in futuro si possa fare loro riferimento senza doverli ridefinire nuovamente. Il procedimento di memorizzazione dei formati in librerie di utente, nonch il loro successivo richiamo, funzione del sistema operativo sul quale il sistema SAS opera; per questo ed altri dettagli circa le possibilit ulteriori offerte dalla procedura FORMAT si consiglia il lettore di consultare il manuale SAS User's Guide: Basics nonch i manuali della serie SAS Companion, relativi al sistema operativo in uso.

6.5.

La procedura FORMS

La PROC FORMS serve per stampare su moduli aventi particolari 206

prefincature o formati (esempio: etichette da apporre su buste, assegni, ecc.). Tutte o solo alcune delle variabili di ciascuna osservazione di un archivio SAS verranno stampate su unit di stampa (form unit), secondo uno schema rettangolare (ad esempio, una etichetta o un modulo prefincato rappresentano una unit di stampa). In funzione del formato dei moduli, si dovranno dare alcune specifiche alla procedura per indicare l'esatta collocazione dei dati da stampare. Facciamo un esempio: si debbano stampare, adoperando moduli prefincati del tipo mostrato in figura 6.1.1, i dati di riepilogo relativi agli emolumenti corrisposti agli impiegati di una azienda; i dati sono contenuti sull'archivio SAS IMPIEGAT mostrato, in parte, in figura 6.2.

ARTIGIANA DESIGN S.r.l.


Riga 4 CEDOLINO PAGA MESE DI ____________ Colonna 23 Riga 7 Riga 8 Riga 10 DIPARTIMENTO ____ Colonna 15 Colonna 32 IMPIEGATO ________________________ Colonna 11 MATRICOLA

RIga 13

STIPENDIO LORDO _____________ Lit. Colonna

17

Riga 16

STIPENDIO NETTO _____________ Lit. Colonna

17

Riga 19

TRATTENUTE

_____________ Lit. Colonna

17

Tipografica Free S.n.c. - Pisa

Figura 6.1.1: Modulo prefincato Il programma mostrato in figura 6.4 si compone di tre passi; il primo definisce due formati, uno per stampare il nome del mese in italiano e l'altro per stampare gli importi alla maniera italiana (la virgola separa la parte intera da quella decimale ed il punto separa le cifre intere in gruppi di tre); nel secondo passo viene creato un archivio temporaneo contenente tutte le variabili dell'archivio A1987.IMPIEGAT pi tre nuove: MESE e ANNO ottenute estraendo la parte mese (tramite la funzioneMONTH) e la parte anno (tramite la funzione 207

YEAR) dalla data dell'elaboratore (generata dalla funzione DATE()); TRATTEN, ottenuta sottraendo il valore dello stipendio netto da quello lordo. L'ultimo passo richiama la PROC FORMS che, oltre a definire le dimensioni del modulo rappresentante il cedolino, specifica le righe e le colonne a partire dalle quali saranno stampati i valori delle variabili in gioco.
OBS MATRICOL DIPARTIM COGNOME STPLORDO STPNETTO 1 2 3 1230 1235 1340 100 200 300 ARETINI BARTOLI CERIANI 100000 120000 300000 90000 110000 250000

Figura 6.2: Alcune osservazioni dell'archivio SAS IMPIEGAT Generalmente il dispositivo di uscita della PROC FORMS rappresentato dalla stampante, ma possibile scrivere i risultati anche su di un archivio esterno, ad esempio su disco, permettendo cos di conservare i risultati, sino a quando non si sar provveduto a montare la opportuna modulistica sulle stampanti in uso. La figura 6.3 mostra una ipotetica pagina composta da quattro unit di stampa (etichette, ad esempio); i numeri cerchiati indicano altrettante opzioni di personalizzazione della PROC FORMS; vediamoli ora in dettaglio.
2 1 3 5 4 6 7

Unit di stampa i-esima

Figura 6.3: Principali opzioni di personalizzazione

208

Figura 6.4: Esempio di programma per la stampa dei cedolini paga


PROC FORMAT; VALUE MESEFMT 1 2 3 4 5 6 7 8 9 10 11 12 = = = = = = = = = = = = 'Gennaio' 'Febbraio' 'Marzo' 'Aprile' 'Maggio' 'Giugno' 'Luglio' 'Agosto' 'Settembre' 'Ottobre' 'Novembre' 'Dicembre';

PICTURE ITALFMT LOW-<0 = '0.000.009,00' (PREFIX='-' MULT=100) 0-HIGH = '0.000.009,00' (MULT=100); DATA CEDOLINI; RETAIN ANNO MESE; SET IMPIEGAT; IF _N_=1 THEN DO; MESE=MONTH(DATE()); ANNO=YEAR(DATE()); END; TRATTEN=STPLORDO-STPNETTO; PROC FORMS DATA=CEDOLINI LINES=24 /* numero massimo di linee della unit di stampa */ SKIP=8 /* numero di righe da saltare, a partire dalla fine di una unit di stampa, sino all'inizio della prossima */ INDENT=1 /* numero di caratteri da saltare per posizionarsi all'inizio della prima unit di stampa della pagina */ WIDTH=45 /* numero massimo di caratteri per riga di ciascuna unit di stampa */ ALIGN=4 /* numero di unit di stampa che verranno, all'inizio della stampa, riempiti con caratteri XXXX, onde permettere il corretto allineamento della stampante */;

* Le dichiarazioni LINE che seguono definiscono, ciascuna, la riga e la colonna di inizio del campo dove stampare la variabile elencata; LINE LINE LINE LINE LINE LINE LINE 4 7 8 10 13 16 19 MESE DIPARTIM MATRICOL COGNOME STPLORDO STPNETTO TRATTEN / / / / / / / INDENT=22; INDENT=14; INDENT=31; INDENT=10; INDENT=16; INDENT=16; INDENT=16;

FORMAT MESE MESEFMT. COGNOME $30. STPLORDO STPNETTO TRATTEN ITALFMT.; RUN;

209

1:

Opzione INDENT (I=n); specifica il numero n di posizioni da saltare per posizionarsi all'inizio della prima unit di stampa della pagina (n dovr essere compreso tra 0 e 200; il valore di default 0). Opzione DOWN (D=n); specifica il numero n di righe da saltare per posizionarsi sulla prima unit di stampa della pagina (n dovr essere compreso tra 0 e 200; il valore di default 0). Opzione WIDTH (W=n); specifica il numero n di posizioni all'interno della i-esima unit di stampa (n dovr essere compreso tra 1 e 255; il valore di default 40). Opzione LINES (L=n); specifica il numero n di linee della i-esima unit di stampa (n dovr essere compreso tra 1 e 255; il valore di default rappresentato dal valore massimo posto in una dichiarazione LINE). Opzione BETWEEN (B=n); specifica il numero n di posizioni tra una unit di stampa e l'altra (n dovr essere compreso tra 0 e 200; il valore di default 1). Opzione SKIP (S=n); specifica il numero n di righe da saltare tra una unit di stampa e l'altra (n dovr essere compreso tra 0 e 200; il valore di default 1). Opzione PAGESIZE (P=n); specifica il numero n di righe presenti su una pagina di stampa (n dovr essere compreso tra il valore di DOWN+LINES e 255; il valore di default 66). Opzione LINESIZE (LS=n) specificabile solo tramite la dichiarazione OPTIONS; specifica il numero di caratteri di stampa di una riga della pagina (n dovr essere compreso tra 64 e 256).

2:

3:

4:

5:

6:

7:

8:

Inoltre, l'opzione NDOWN (ND=n) e NACROSS (NA=n) specificano il numero di unit di stampa presenti sulla pagina, rispettivamente, in verticale ed in orizzontale.

6.6.

La procedura CHART

La CHART una procedura usata per produrre: istogrammi(bar chart), verticali od orizzontali, diagrammi a blocchi (block chart), ideogrammi circolari (pie chart) o stellari (star chart). Mediante questa procedura possibile, ad esempio, mostrare graficamente con un istogramma come si distribuiscono i valori di una variabile, numerica od alfanumerica, di un archivio SAS, oppure comparare le distribuzioni di due o pi variabili SAS. Affinch la procedura possa produrre i risultati desiderati occorre fornirle alcune informazioni di base. 210

tipo di rappresentazione grafica desiderata (istogramma, ideogramma, diagramma a blocchi, ecc.); variabile/i oggetto di analisi; significato dell'altezza di ogni barra (blocco), o dell'area di un settore dell'ideogramma, cio la misura associata (es.: la frequenza, la somma, ecc.); indicazioni relative al criterio secondo il quale i valori della/e variabile/i di analisi dovranno essere raggruppati prima della loro rappresentazione grafica. La sintassi della procedura CHART la seguente: PROC CHART [opzioni]; BY variabile/i; VBAR variabile/i / [opzioni]; HBAR variabile/i / [opzioni]; BLOCK variabile/i / [opzioni]; PIE variabile/i / [opzioni]; STAR variabile/i / [opzioni]; Al termine di questo paragrafo sono elencate le principali opzioni di personalizzazione permesse nelle dichiarazioni di questa procedura. A titolo d'esempio, supponiamo di voler analizzare i dati dell'archivio SAS VENDITE di figura 6.5; in particolare, desideriamo ottenere un istogramma verticale che riporti tante barre verticali quanti sono i rappresentanti presenti nell'archivio; inoltre l'altezza di ciascuna barra dovr essere proporzionale al numero di osservazioni relative a quel rappresentante, cio al numero delle vendite effettuate. Il programma di figura 6.6 realizza quanto richiesto e la figura 6.7 rappresenta i risultati ottenuti.
OBS NOMERAP DATAVE ARTICOLO NUMERO COSTO TOTALE MESE GIORNO

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

Artale Artale Artale Artale Artale Artale Artale Artale Artale Banti Banti Banti Banti Banti Banti Banti Banti Banti

03/01/87 05/01/87 05/01/87 13/02/87 14/02/87 17/02/87 03/03/87 04/03/87 10/03/87 03/01/87 03/01/87 05/02/87 13/02/87 16/02/87 16/02/87 10/03/87 16/03/87 21/03/87

Cartucce Scheda I/O Interfaccia GPX Video a colori Package "Multiplan" Video bianco-nero Pacco carta A4 Pennarelli plotter Cartucce Interfaccia KSP Package "Astra" Video a colori Pacco di carta A3 Package "Multiplan" Scheda I/O Scheda I/O Pennarelli plotter Pacco carta A4

10 1 2 1 1 1 20 10 20 1 1 3 30 1 1 2 20 10

5000 50000 150000 150000 400000 800000 200000 200000 180000 180000 150000 150000 4000 80000 5700 57000 5000 100000 275000 275000 400000 400000 600000 1800000 5000 150000 180000 180000 150000 150000 150000 300000 5700 114000 4000 40000

1 1 1 2 2 2 3 3 3 1 1 2 2 2 2 3 3 3

7 2 2 6 7 3 3 4 3 7 7 5 6 2 2 3 2 7

Figura 6.5: Archivio usato negli esempi di PROC CHART 211

PROC CHART DATA=VENDITE; VBAR NOMERAP; TITLE 'NUMERO DI VENDITE NEL PERIODO'; FOOTNOTE 'A CURA DEL DIPARTIMENTO COMMERCIALE'; RUN;

Figura 6.6: Esempio di uso della dichiarazione VBAR Nel programma di figura 6.6, la dichiarazione VBAR (Vertical BAR) richiede un istogramma verticale; a ciascun valore diverso assunto dalla variabile NOMERAP verr associata una barra. In assenza di opzioni di personalizzazione, la procedura assume che l'altezza di ciascuna barra sia proporzionale alla frequenza con la quale quel valore della variabile appare.

NUMERO DI VENDITE NEL PERIODO FREQUENCY BAR CHART FREQUENCY 9 + ***** ***** | ***** ***** 8 + ***** ***** | ***** ***** 7 + ***** ***** | ***** ***** 6 + ***** ***** | ***** ***** 5 + ***** ***** | ***** ***** 4 + ***** ***** | ***** ***** 3 + ***** ***** | ***** ***** 2 + ***** ***** | ***** ***** 1 + ***** ***** | ***** ***** ------------------------Artale Banti NOMERAP A CURA DEL DIPARTIMENTO COMMERCIALE

Figura 6.7: Risultati del programma di figura 6.6 Inoltre, in assenza di opzioni di personalizzazione che specifichino il contrario, i valori mancanti non saranno considerati validi agli effetti dell'analisi e ad essi non corrisponder alcuna barra. Per ottenere un istogramma quantitativamente pi ricco di informazioni rispetto a quello mostrato in figura 6.7, baster sostituire la dichiarazione VBAR con HBAR (Horizontal BAR) ottenendo la figura 6.8. Se si desidera una rappresentazione qualitativamente pi efficace, ad esempio trasformando da due a tre le dimensioni dell'istogramma, 212

baster eseguire il programma di figura 6.9 ottenendo i risultati mostrati in figura 6.10.
NUMERO DI VENDITE NEL PERIODO FREQUENCY BAR CHART NOMERAP | |****************** | |****************** | ----+---+---+---+-2 4 6 8 FREQUENCY FREQ CUM. FREQ 9 18 PERCENT CUM. PERCENT 50.00 100.00

Artale Banti

9 9

50.00 50.00

A CURA DEL DIPARTIMENTO COMMERCIALE

Figura 6.8: Risultati del programma di figura 6.6 con HBAR


PROC CHART DATA=VENDITE; BLOCK NOMERAP / GROUP=NOMERAP; TITLE 'NUMERO DI VENDITE NEL PERIODO'; FOOTNOTE 'A CURA DEL DIPARTIMENTO COMMERCIALE';

Figura 6.9: Esempio di uso della dichiarazione BLOCK


NUMERO DI VENDITE NEL PERIODO FREQUENCY BLOCK CHART .__. /_./| |**| | |**| | |**| | |**| | |**| | NOMERAP .__._______________|**| |_______ /_./| / |**| | / |**| | / |**| | / Banti |**| | / |**| | / |**| | / |**|/ / |**| | / -/ |**| | / 9 / /|**| |_______/_____________/ / |**| | / / / |**| | / / Artale / |**| | / / / |**|/ / / / -/ / / 9 / / /_____________/_____________/ Artale Banti NOMERAP A CURA DEL DIPARTIMENTO COMMERCIALE

Figura 6.10: Risultati del programma di figura 6.9 Nella dichiarazione BLOCK del programma di figura 6.9, il carattere "/" segnala l'inizio della parte di dichiarazione riservata alle opzioni di personalizzazione. In questo caso la presenza di GROUP=, pur segnalando che i dati di vendita dovranno essere raggruppati logicamente per venditore, serve solo per permettere una rappresentazione grafica a tre dimensioni. 213

Non sempre possibile evidenziare immediatamente, su terminale o stampante, un istogramma verticale o a blocchi in quanto le dimensioni della pagina possono risultare insufficienti alla procedura. In questi casi la CHART trasforma "d'ufficio" il disegno richiesto in un istogramma orizzontale come se fosse stato prodotto da una dichiarazione HBAR. Per modificare le dimensioni della pagina occorre inserire prima della PROC CHART, una dichiarazione OPTIONS che cambi i parametri LINESIZE e/o PAGESIZE della sessione o del programma corrente. Si supponga ora di volere un istogramma orizzontale che mostri, per ciascun venditore, come si distribuiscono, per prodotto, le vendite da lui operate in un determinato periodo.
PROC CHART DATA=VENDITE; HBAR ARTICOLO / GROUP=NOMERAP; TITLE TOTALE DELLE VENDITE PER VENDITORE/ARTICOLO'; RUN;

Figura 6.11: Esempio di uso della PROC CHART Il programma di figura 6.11 produrr l'istogramma rappresentato in figura 6.13. In questo caso baster usare una dichiarazione HBAR seguita dal nome della variabile a cui associare le barre orizzontali (ARTICOLO). Nella dichiarazione HBAR del programma di figura 6.11, la barra (slash) segnala l'inizio della parte riservata ad eventuali opzioni di personalizzazione. La presenza dell'opzione GROUP= indica che gli articoli venduti dovranno essere raggruppati logicamente per venditore. Continuando nell'analisi dei dati di vendita, si desidera ora produrre un ideogramma circolare avente tanti settori per quanti sono i rappresentanti, e in cui l'area di ogni settore sia proporzionale alla sommatoria degli importi di ciascuna vendita effettuata dal rappresentante associato a quel settore. Il programma di figura 6.12 realizza quanto richiesto producendo la figura 6.15. In questo caso, la presenza dell'opzione SUMVAR= segnala che i valori della variabile TOTALE relativi all'i-esimo venditore dovranno essere sommati tra loro e che quindi l'area dell'iesimo settore sar proporzionale al valore assunto da detta sommatoria. Non si pu certo dire che il risultato ottenuto sia brillante! Si tenga presente tuttavia che tutti i grafici della PROC CHART debbono funzionare con dispositivi privi di caratteristiche grafiche. Un sostanziale miglioramento per la produzione di ideogrammi, si ottiene per mezzo della componente SAS/GRAPH, ed un esempio verr mostrato nel capitolo 10. 214

PROC CHART DATA=VENDITE; PIE NOMERAP / SUMVAR=TOTALE; TITLE 'DISTRIBUZIONE DEL FATTURATO PER VENDITORE'; RUN;

Figura 6.12: Esempio di uso della dichiarazione PIE


_

TOTALE DELLE VENDITE PER VENDITORE/ARTICOLO FREQUENCY BAR CHART NOMERAP Artale ARTICOLO Cartucce Interfaccia GPX Interfaccia KSP Pacco carta A4 Pacco di carta A Package "Astra" Package "Multipl Pennarelli plott Scheda I/O Video a colori Video bianco-ner Cartucce Interfaccia GPX Interfaccia KSP Pacco carta A4 Pacco di carta A Package "Astra" Package "Multipl Pennarelli plott Scheda I/O Video a colori Video bianco-ner | |******************** |********** | |********** | | |********** |********** |********** |********** |********** | | | |********** |********** |********** |********** |********** |********** |******************** |********** | | ----------+---------+ 1 2 FREQUENCY FREQ 2 1 0 1 0 0 1 1 1 1 1 0 0 1 1 1 1 1 1 2 1 0 PERCENT 11.11 5.56 0.00 5.56 0.00 0.00 5.56 5.56 5.56 5.56 5.56 0.00 0.00 5.56 5.56 5.56 5.56 5.56 5.56 11.11 5.56 0.00

Banti

Figura 6.13: Risultati del programma di figura 6.11 Si conclude questa panoramica sull'uso della procedura CHART mostrando un esempio nel quale si richiede un istogramma a blocchi mediante il quale si possa vedere come si distribuisce il fatturato per venditore e per mese. Il programma di figura 6.14 realizza quanto richiesto e produce l'uscita di figura 6.16.
PROC FORMAT; VALUE MESEFM 1='Gennaio' 2='Febbraio' 3='Marzo'; PROC CHART DATA=VENDITE; BLOCK MESE/SUMVAR=TOTALE GROUP=NOMERAP DISCRETE; TITLE 'DISTRIBUZIONE DEL FATTURATO'; FORMAT MESE MESEFM.; RUN;

Figura 6.14: Esempio di uso della PROC CHART 215

La dichiarazione BLOCK contiene tre opzioni di personalizzazione: SUMVAR=, GROUP= e DISCRETE. La prima delle tre segnala che l'altezza di ciascun blocco deve essere proporzionale alla somma dei valori assunti dalla variabile TOTALE.

La seconda richiede un raggruppamento logico dei dati per ciascun venditore. Infine, l'ultima informa la procedura che MESE una variabile che assume valori discreti e, che a ciascun valore diverso di essa, corrisponder un blocco nel rapporto di figura 6.16. Qualora avessimo omesso l'opzione DISCRETE, la procedura avrebbe assunto come continui i valori della variabile MESE e l'uscita sarebbe risultata incomprensibile. Si deve sottolineare che l'opzione DISCRETE si riferisce alla variabile specificata dopo BLOCK (cio MESE) e non alla variabile specificata dopo SUMVAR (cio TOTALE) che continua.
DISTRIBUZIONE DEL FATTURATO PER VENDITORE SUM PIE CHART OF TOTALE GROUPED BY NOMERAP

****************** Artale **** *** **. *** ** . *** ** . *** ** .. ** ** . 1767000 ** * . 34.14% ** * . ** * .. * * . ** * . * * * * + . . . . . . . . . .* * * * * * * * ** * * * ** ** ** ** 3409000 ** ** 65.86% ** ** *** ** *** ** *** **** *** Banti ********* ******** *

Figura 6.15: Risultati del programma di figura 6.12

216

DISTRIBUZIONE DEL FATTURATO BLOCK CHART OF TOTALE SUMS .__. /_./| |**| | |**| | |**| | |**| | |**| | NOMERAP ___.__.________|**| |_____________________ / /_./| / |**| | / .__. / / |**| | / |**| | / /_./| / Banti / |**| | / |**| | / |**| | / / |**|/ / |**|/ / |**|/ / / ---/ / / / / / .__. 675000 / 2280000 / 454000 / /_/_./|_______/_____________/_____________/ / |**| | / .__. / / / |**| | / /_./| / .__. / Artale/ |**| | / |**| | / /_./| / / |**|/ / |**|/ / |**|/ / / ---/ / / / / / 1000000 / 530000 / 237000 / /_____________/_____________/_____________/ Gennaio Febbraio MESE Marzo

Figura 6.16: Risultati del programma di figura 6.14 Principali opzioni della procedura CHART Le sole opzioni della dichiarazione PROC CHART sono: DATA= <nome-archivio-SAS> LPI=p dove p specifica le proporzioni degli ideogrammi ottenibili dalle dichiarazioni PIE e STAR; in particolare, in funzione delle caratteristiche del dispositivo di uscita di cui si dispone, p=(linee per pollice/colonne per pollice)*10. Il valore di default 6. Di seguito sono elencate alcune delle principali opzioni valide per le dichiarazioni VBAR, HBAR, BLOCK, PIE e STAR: MISSING specifica che i valori mancanti devono essere considerati valori validi a cui associare barre o settori. DISCRETE specifica che la variabile numerica oggetto di analisi assume valori discreti. Se questa opzione non presente, la procedura suppone che la variabile assuma valori continui e, in assenza della opzione MIDPOINTS=, vengono scelti 217

automaticamente i baricentri delle classi rappresentate da barre o settori. TYPE=parola-chiave specifica a cosa dovr essere proporzionale la dimensione di ciascuna barra o settore della rappresentazione grafica; in particolare, parola-chiave potr essere: FREQ la frequenza con cui un valore (o un insieme di valori afferenti ad una specifica classe) stato incontrato; in mancanza della opzione SUMVAR=, il sistema SAS assume che l'altezza delle barre sia proporzionale alla frequenza dei valori della variabile oggetto di analisi. PERCENT la percentuale di osservazioni che assumono un dato valore (o rientrano in una data classe). CFREQ o CPERCENT rispettivamente, cumulativa. SUM la frequenza o la percentuale

la sommatoria dei valori della variabile specificata nella opzione SUMVAR=. MEAN il valor medio dei valori della variabile specificata nella opzione SUMVAR=. SUMVAR=variabile rappresenta il nome di una variabile i cui valori saranno elaborati in funzione dell'opzione TYPE=. Come mostrato nell'esempio di figura 6.14, se viene usata l'opzione SUMVAR= in assenza della TYPE=, la procedura assume automaticamente TYPE=SUM. MIDPOINTS=valori rappresenta l'insieme dei punti di mezzo (o baricentri) che saranno associati a ciascuna barra o settore della rappresentazione grafica; detti valori, numerici o alfanumerici, potranno essere elencati secondo le forme seguenti: 1) 2) una lista di valori numerici, esempio: 5 10 15 20 25 30; una forma ripetitiva del tipo: 5 TO 30 BY 5 che genera i seguenti baricentri con passo 5: 5 10 15 20 25 30; 218

3)

una forma ripetitiva del tipo: 10 TO 1 BY -1 che genera i seguenti baricentri con passo -1: 10 9 8 7 6 5 4 3 2 1; una lista di stringhe racchiuse tra apici del tipo: 'Gennaio' 'Febbraio' 'Marzo' 'Aprile' ecc. ecc..

4) AXIS=valore

serve per specificare il valore massimo da usarsi per la definizione della scala dell'asse delle ordinate (in caso di VBAR) o delle ascisse (in caso di HBAR). Detto valore pu essere anche negativo. Alcune altre opzioni valide solo nel contesto delle dichiarazioni BLOCK, HBAR e VBAR sono: SUBGROUP=variabile comanda la suddivisione di ciascuna barra o blocco in tante parti quanti sono i valori diversi assunti da variabile (valori mancanti compresi); variabile pu essere sia numerica che non numerica; ciascuna parte di barra viene normalmente riempita con il primo carattere della variabile. Nel caso che pi valori di variabile comincino per lo stesso carattere (es.: "ARTALE" e "ARTOM") la procedura usa i caratteri: A, B, C, ecc.. LEVELS=n nel caso che la variabile specificata nella VBAR assuma valori continui, mediante questa opzione possibile specificare che il numero delle barre dell'istogramma dovr essere n.

6.7.

La procedura CALENDAR

La procedura CALENDAR in grado di produrre rapporti del tipo: sommario pianificazione.

Si definiscono di "sommario" quei rapporti nei quali i valori delle variabili di un archivio SAS vengono rappresentati in funzione del tempo in forma di calendario. I rapporti di tipo "pianificazione" mostrano, rappresentandola con una riga di caratteri "=", la durata di eventi (ad esempio: le varie fasi in cui possibile suddividere un lavoro). In quest'ultimo tipo di rapporti (dei quali non saranno prodotti esempi nel testo), ogni evento rappresentato da una osservazione; un evento pu essere associato ad uno o pi periodi temporali (giorni, settimane o mesi) in funzione della sua durata complessiva. 219

Mediante le dichiarazioni HOLIDAYS e HOLINAME possibile personalizzare le uscite della procedura mediante l'indicazione dei giorni e del tipo di festivit da considerare; in particolare, quando si usano queste due dichiarazioni, occorre che nella PROC CALENDAR sia specificata l'opzione HOLIDATA= seguita dal nome dell'archivio SAS contenente le variabili i cui valori rappresentano, rispettivamente, le date ed i nomi delle festivit; i nomi di queste variabili debbono essere elencati nelle dichiarazione HOLIDAYS e HOLINAME. La sintassi della procedura la seguente:
PROC CALENDAR [opzioni]; BY variabili; ID variabile; VAR variabili; SUM variabili / opzioni; /*Da usarsi per rapporti di sommario */ MEAN variabili / opzioni; /*Da usarsi per rapporti di sommario */ DURATION variabile; /*Da usarsi per rapporti di pianificazione */ HOLIDAYS variabili; HOLINAME variabili;

Come esempio di applicazione, si pensi di avere a disposizione un archivio SAS di nome VENDITE contenente osservazioni come quelle mostrate in figura 6.5 e le seguenti variabili: NOMERAP cognome e nome del rappresentante; DATAVE TOTALE data in cui stata effettuata la vendita; importo del prodotto venduto. ARTICOLO codice del prodotto venduto; Supponiamo che il direttore commerciale abbia necessit di conoscere come si distribuiscono le vendite effettuate all'interno di un mese di riferimento (es. gennaio), cio necessiti di un tabulato a forma di calendario nel quale, per ciascun giorno della settimana e per tutta la durata del mese, sia riportato il totale delle vendite effettuate da tutti i rappresentanti. Per ottenere questo si potr utilizzare la PROC CALENDAR, ma occorrer prima organizzare i dati dell'archivio di figura 6.5 in modo tale che: essi siano ordinati in funzione della variabile contenente la data di vendita (DATAVE); esista una sola osservazione, per ciascuna data di vendita, contenente l'importo totale delle vendite effettuate in quel giorno.

220

I primi due passi del programma mostrato in figura 6.17 produrranno l'archivio temporaneo ESTRATTO di figura 6.17.1 che sar utilizzato nell'ultimo passo dalla PROC CALENDAR per generare il rapporto rappresentato nelle figure 6.18.1 e 6.18.2. Si noti che detto archivio si compone di tante osservazioni quanti sono i giorni nei quali stata effettuata almeno una vendita; ciascuna osservazione contiene: la data (DATAVE) ed il totale delle vendite effettuate in quella data (TOTVEND).
PROC SORT DATA=VENDITE; BY DATAVE; PROC MEANS DATA=VENDITE NOPRINT; VAR TOTALE; BY DATAVE; OUTPUT OUT=ESTRATTO; /* CREA ARCHIVIO SAS ESTRATTO */ SUM=TOTVEND; /* CON VARIAB. DATAVE TOTVEND */ PROC PRINT DATA=ESTRATTO; FORMAT DATAVE DDMMYY8.; PROC CALENDAR DATA=ESTRATTO; ID DATAVE; VAR TOTVEND; TITLE 'Distribuzione vendite del periodo'; FOOTNOTE 'a cura del Dipartimento Commerciale'; RUN;

Figura 6.17: Esempio di uso della PROC CALENDAR

OBS 1 2 3 4 5 6 7 8 9 10 11 12

DATAVE

TOTVEND

03/01/87 725000 05/01/87 950000 05/02/87 1800000 13/02/87 350000 14/02/87 180000 15/02/87 150000 16/02/87 330000 03/03/87 80000 04/03/87 57000 10/03/87 400000 16/03/87 114000 21/03/87 40000

Figura 6.17.1: Archivio SAS ESTRATTO Come si pu notare osservando l'ultimo passo del programma di figura 6.17, per un corretto uso della procedura richiesto che: la variabile DATAVE sia elencata nella dichiarazione ID; necessario che la variabile elencata in questa dichiarazione sia di tipo data o data-tempo; nel caso la variabile sia di tipo data-tempo, occorre che nella dichiarazione PROC CALENDAR sia specificata l'opzione DATETIME. 221

L'archivio di ingresso per la procedura dovr essere gi ordinato in base ai valori della variabile elencata nella ID. la variabile TOTVEND, da far comparire nel riquadro destinato a rappresentare ciascun giorno del mese, sia elencata della dichiarazione VAR.
Distribuzione vendite del periodo
----------------------------------------------------------------------| JANUARY 1987 | |---------------------------------------------------------------------| | SUNDAY | MONDAY | TUESDAY |WEDNESDAY|THURSDAY | FRIDAY |SATURDAY | |---------+---------+---------+---------+---------+---------+---------| | | | | | 1 | 2 | 3 | | | | | | | | _| | | | | | | | 725000| |---------+---------+---------+---------+---------+---------+---------| | 4 | 5 | 6 | 7 | 8 | 9 | 10 | | | | | | | | | | | 950000| | | | | | |---------+---------+---------+---------+---------+---------+---------| | 11 | 12 | 13 | 14 | 15 | 16 | 17 | | | | | | | | | | | | | | | | | |---------+---------+---------+---------+---------+---------+---------| | 18 | 19 | 20 | 21 | 22 | 23 | 24 | | | | | | | | | | | | | | | | | |---------+---------+---------+---------+---------+---------+---------| | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | | | | | | | | | | | | | | | | --------------------------------------------------------------------------------------------------------------------------------------------| FEBRUARY 1987 | |---------------------------------------------------------------------| | SUNDAY | MONDAY | TUESDAY |WEDNESDAY|THURSDAY | FRIDAY |SATURDAY | |---------+---------+---------+---------+---------+---------+---------| | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | | | | | | | | | | | | | 1800000| | | |---------+---------+---------+---------+---------+---------+---------| | 8 | 9 | 10 | 11 | 12 | 13 | 14 | | | | | | | | | | | | | | | 350000| 180000| |---------+---------+---------+---------+---------+---------+---------| | 15 | 16 | 17 | 18 | 19 | 20 | 21 | | | | | | | | | | 150000| 330000| | | | | | |---------+---------+---------+---------+---------+---------+---------| | 22 | 23 | 24 | 25 | 26 | 27 | 28 | | | | | | | | | | | | | | | | | -----------------------------------------------------------------------

Figura 6.18.1: Risultato del programma di figura 6.17 (continua)

222

----------------------------------------------------------------------| MARCH 1987 | |---------------------------------------------------------------------| | SUNDAY | MONDAY | TUESDAY |WEDNESDAY|THURSDAY | FRIDAY |SATURDAY | |---------+---------+---------+---------+---------+---------+---------| | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | | | | | | | | | | | 80000| 57000| | | | |---------+---------+---------+---------+---------+---------+---------| | 8 | 9 | 10 | 11 | 12 | 13 | 14 | | | | | | | | | | | | 400000| | | | | |---------+---------+---------+---------+---------+---------+---------| | 15 | 16 | 17 | 18 | 19 | 20 | 21 | | | | | | | | | | | 114000| | | | | 40000| |---------+---------+---------+---------+---------+---------+---------| | 22 | 23 | 24 | 25 | 26 | 27 | 28 | | | | | | | | | | | | | | | | | |---------+---------+---------+---------+---------+---------+---------| | 29 | 30 | 31 | | | | | | | | | | | | | | | | | | | | | -----------------------------------------------------------------------

a cura del Dipartimento Commerciale

Figura 6.18.2: Risultato del programma di figura 6.17 Supponiamo ora che il direttore commerciale sia interessato a vedere evidenziati sui rapporti: il totale mensile delle vendite; l'importo medio delle vendite del mese, dato da: totale mensile diviso il numero di giorni del mese in cui sono state effettuate vendite. In questo caso, occorrer eseguire il programma mostrato figura 6.19.

PROC CALENDAR DATA=ESTRATTO; ID DATAVE; VAR TOTVEND; LABEL TOTVEND='TOTALE E IMPORTO MEDIO DELLE VENDITE'; SUM TOTVEND /* richiesta di totale generale */; MEAN TOTVEND /* richiesta di importo medio */; TITLE 'Distribuzione vendite del periodo'; TITLE2 'con totale e importo medio'; FOOTNOTE 'a cura del Dipartimento Commerciale'; RUN;

Figura 6.19: Esempio di uso della PROC CALENDAR con richiesta di totalizzazione e calcolo del valor medio del venduto

223

Distribuzione vendite del periodo con totale e importo medio


----------------------------------------------------------------------| JANUARY 1987 | |---------------------------------------------------------------------| | SUNDAY | MONDAY | TUESDAY |WEDNESDAY|THURSDAY | FRIDAY |SATURDAY | |---------+---------+---------+---------+---------+---------+---------| | | | | | 1 | 2 | 3 | | | | | | | | | | | | | | | | 725000| |---------+---------+---------+---------+---------+---------+---------| | 4 | 5 | 6 | 7 | 8 | 9 | 10 | | | | | | | | | | | 950000| | | | | | |---------+---------+---------+---------+---------+---------+---------| | 11 | 12 | 13 | 14 | 15 | 16 | 17 | | | | | | | | | | | | | | | | | |---------+---------+---------+---------+---------+---------+---------| | 18 | 19 | 20 | 21 | 22 | 23 | 24 | | | | | | | | | | | | | | | | | |---------+---------+---------+---------+---------+---------+---------| | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | | | | | | | | | | | | | | | | ---------------------------------------------------------------------------------------------------------------------------------------------| | SUM | MEAN | | TOTALE E IMPORTO MEDIO DELLE VENDITE | 1675000 | 837500 | ------------------------------------------------------------------------

----------------------------------------------------------------------| FEBRUARY 1987 | |---------------------------------------------------------------------| | SUNDAY | MONDAY | TUESDAY |WEDNESDAY|THURSDAY | FRIDAY |SATURDAY | |---------+---------+---------+---------+---------+---------+---------| | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | | | | | | | | | | | | | 1800000| | | |---------+---------+---------+---------+---------+---------+---------| | 8 | 9 | 10 | 11 | 12 | 13 | 14 | | | | | | | | | | | | | | | 350000| 180000| |---------+---------+---------+---------+---------+---------+---------| | 15 | 16 | 17 | 18 | 19 | 20 | 21 | | | | | | | | | | 150000| 330000| | | | | | |---------+---------+---------+---------+---------+---------+---------| | 22 | 23 | 24 | 25 | 26 | 27 | 28 | | | | | | | | | | | | | | | | | ---------------------------------------------------------------------------------------------------------------------------------------------| | SUM | MEAN | | TOTALE E IMPORTO MEDIO DELLE VENDITE | 2810000 | 562000 | ------------------------------------------------------------------------

Figura 6.20.1: Risultato del programma di figura 6.19 (continua)

224

----------------------------------------------------------------------| MARCH 1987 | |---------------------------------------------------------------------| | SUNDAY | MONDAY | TUESDAY |WEDNESDAY|THURSDAY | FRIDAY |SATURDAY | |---------+---------+---------+---------+---------+---------+---------| | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | | | | | | | | | | | 80000| 57000| | | | |---------+---------+---------+---------+---------+---------+---------| | 8 | 9 | 10 | 11 | 12 | 13 | 14 | | | | | | | | | | | | 400000| | | | | |---------+---------+---------+---------+---------+---------+---------| | 15 | 16 | 17 | 18 | 19 | 20 | 21 | | | | | | | | | | | 114000| | | | | 40000| |---------+---------+---------+---------+---------+---------+---------| | 22 | 23 | 24 | 25 | 26 | 27 | 28 | | | | | | | | | | | | | | | | | |---------+---------+---------+---------+---------+---------+---------| | 29 | 30 | 31 | | | | | | | | | | | | | | | | | | | | | ---------------------------------------------------------------------------------------------------------------------------------------------| | SUM | MEAN | | TOTALE E IMPORTO MEDIO DELLE VENDITE | 691000 | 138200 | ------------------------------------------------------------------------

a cura del Dipartimento Commerciale

Figura 6.20.2: Risultato del programma di figura 6.19 Nel programma di figura 6.19, si nota la presenza di due nuove dichiarazioni: SUM e MEAN. La prima delle due specifica le variabili che devono essere totalizzate per ciascun mese. La dichiarazione MEAN specifica le variabili per le quali richiesto il calcolo del valore medio mensile. Entrambi queste dichiarazioni possono apparire in una procedura pi volte ed inoltre possibile assegnare alle variabili elencate in esse dei formati di uscita secondo la seguente sintassi: SUM variabili / FORMAT=<nome_del_formato.>; MEAN variabili / FORMAT=<nome_del_formato.>; Come si vede dalle figure 6.20.1 e 6.20.2, l'uscita di questa procedura si compone delle seguenti parti: eventuali titoli inseriti dall'utente; riga di testata riportante: il nome del mese e dell'anno che la procedura trova nei dati; riga di testata riportante: i nomi dei giorni della settimana;

225

i dati specificati dall'utente, per ciascun giorno, settimana dopo settimana; un'eventuale riga di riepilogo a fondo pagina contenente sommatorie e valori medi. Se si desiderasse calcolare l'importo medio delle vendite non rispetto al numero di giorni in cui sono state effettuate vendite nel mese, bens rispetto al numero di giorni del mese, occorrerebbe specificare l'opzione MEANTYPE=NDAYS come mostrato nel programma di figura 6.21, ottenendo come risultato le tabelle di figure 6.22.1 e 6.22.2.
PROC CALENDAR DATA=ESTRATTO MEANTYPE=NDAYS; ID DATAVE; VAR TOTVEND; LABEL TOTVEND='TOTALE E IMPORTO MEDIO DELLE VENDITE'; SUM TOTVEND /* richiesta di totale generale */; MEAN TOTVEND /* richiesta di importo medio */; TITLE 'Distribuzione vendite del periodo'; TITLE2 'con totale e importo medio'; FOOTNOTE 'a cura del Dipartimento Commerciale'; RUN;

Figura 6.21: Esempio di uso della PROC CALENDAR


Distribuzione vendite del periodo con totale e importo medio
----------------------------------------------------------------------| JANUARY 1987 | |---------------------------------------------------------------------| | SUNDAY | MONDAY | TUESDAY |WEDNESDAY|THURSDAY | FRIDAY |SATURDAY | |---------+---------+---------+---------+---------+---------+---------| | | | | | 1 | 2 | 3 | | | | | | | | | | | | | | | | 725000| |---------+---------+---------+---------+---------+---------+---------| | 4 | 5 | 6 | 7 | 8 | 9 | 10 | | | | | | | | | | | 950000| | | | | | |---------+---------+---------+---------+---------+---------+---------| | 11 | 12 | 13 | 14 | 15 | 16 | 17 | | | | | | | | | | | | | | | | | |---------+---------+---------+---------+---------+---------+---------| | 18 | 19 | 20 | 21 | 22 | 23 | 24 | | | | | | | | | | | | | | | | | |---------+---------+---------+---------+---------+---------+---------| | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | | | | | | | | | | | | | | | | ---------------------------------------------------------------------------------------------------------------------------------------------| | SUM | MEAN | | TOTALE E IMPORTO MEDIO DELLE VENDITE | 1675000 | 54032.258 | ------------------------------------------------------------------------

Figura 6.22.1: Risultato del programma di figura 6.21 (continua)

226

----------------------------------------------------------------------| FEBRUARY 1987 | |---------------------------------------------------------------------| | SUNDAY | MONDAY | TUESDAY |WEDNESDAY|THURSDAY | FRIDAY |SATURDAY | |---------+---------+---------+---------+---------+---------+---------| | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | | | | | | | | | | | | | 1800000| | | |---------+---------+---------+---------+---------+---------+---------| | 8 | 9 | 10 | 11 | 12 | 13 | 14 | | | | | | | | | | | | | | | 350000| 180000| |---------+---------+---------+---------+---------+---------+---------| | 15 | 16 | 17 | 18 | 19 | 20 | 21 | | | | | | | | | | 150000| 330000| | | | | | |---------+---------+---------+---------+---------+---------+---------| | 22 | 23 | 24 | 25 | 26 | 27 | 28 | | | | | | | | | | | | | | | | | ---------------------------------------------------------------------------------------------------------------------------------------------| | SUM | MEAN | | TOTALE E IMPORTO MEDIO DELLE VENDITE | 2810000 | 100357.14 | ---------------------------------------------------------------------------------------------------------------------------------------------| MARCH 1987 | |---------------------------------------------------------------------| | SUNDAY | MONDAY | TUESDAY |WEDNESDAY|THURSDAY | FRIDAY |SATURDAY | |---------+---------+---------+---------+---------+---------+---------| | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | | | | | | | | | | | 80000| 57000| | | | |---------+---------+---------+---------+---------+---------+---------| | 8 | 9 | 10 | 11 | 12 | 13 | 14 | | | | | | | | | | | | 400000| | | | | |---------+---------+---------+---------+---------+---------+---------| | 15 | 16 | 17 | 18 | 19 | 20 | 21 | | | | | | | | | | | 114000| | | | | 40000| |---------+---------+---------+---------+---------+---------+---------| | 22 | 23 | 24 | 25 | 26 | 27 | 28 | | | | | | | | | | | | | | | | | |---------+---------+---------+---------+---------+---------+---------| | 29 | 30 | 31 | | | | | | | | | | | | | | | | | | | | | ---------------------------------------------------------------------------------------------------------------------------------------------| | SUM | MEAN | | TOTALE E IMPORTO MEDIO DELLE VENDITE | 691000 | 22290.323 | ------------------------------------------------------------------------

a cura del Dipartimento Commerciale

Figura 6.22.2: Risultato del programma di figura 6.21 Se nella dichiarazione PROC CALENDAR comparisse l'opzione WEEKDAYS, la procedura mostrerebbe soltanto i giorni lavorativi della settimana, cio sarebbero esclusi dal computo i giorni: sabato e domenica. In generale, la PROC CALENDAR tenta di far entrare un rapporto in una pagina singola, in funzione delle dimensioni di pagina in azione al momento (opzioni LINESIZE e PAGESIZE, in caso di stampa, e TLINESIZE in caso di uscita sul terminale). La PROC CALENDAR tratta i valori mancanti in modo diverso in funzione di dove essi appaiono e a secondo del tipo di rapporto 227

che si richiesto. Anche la presenza o l'assenza della MISSING nella dichiarazione PROC pu modificare il trattamento. Ad esempio, se un valore della variabile elencata nella ID mancante l'osservazione non viene presa in considerazione sia nel caso di una rapporto di sommario che di pianificazione.

6.8.

La procedura TABULATE

La PROC TABULATE permette la costruzione di tabelle gerarchiche relative a variabili di un archivio SAS. La necessit di fornire agli utenti uno strumento generalizzato per la produzione di tabelle che esprimessero, in forma chiara e concisa, le relazioni esistenti tra variabili di un archivio SAS, indusse il SAS Institute Inc. a prendere lo spunto da un sistema software realizzato dal Dipartimento del Lavoro degli Stati Uniti (U.S. Bureau of Labor), chiamato TPL (Table Producing Language), ed a realizzare la PROC TABULATE, inserendola per la prima volta nella versione '82 del prodotto. La PROC TABULATE possiede caratteristiche di raggruppamento e di analisi dei dati gi presenti in altre procedure come: MEANS, SUMMARY, FREQ ma, in aggiunta, permette di organizzare i risultati in forma sinottica a scelta dell'utente, il quale pu operare delle personalizzazioni sull'aspetto esteriore della tabella permettendone un uso immediato senza la necessit di aggiustamenti grafici successivi. Le tabelle producibili dalla TABULATE possono avere una, due o tre dimensioni corrispondenti, rispettivamente, alle dimensioni di pagina, riga e colonna. Ogni dimensione permette la rappresentazione di una o pi variabili, disposte in modo contiguo, oppure organizzate in modo gerarchico. La PROC TABULATE costruisce tabelle di statistiche descrittive a partire dai seguenti tipi di variabili: di classificazione o di classe; di analisi. Le variabili di classe possono essere di tipo alfanumerico o numerico (intero o decimale), e normalmente ciascuna variabile di classe ha un piccolo numero di valori possibili o di livelli. Le variabili numeriche continue dovranno essere discretizzate (raggruppate in livelli discreti) mediante l'uso di formati definiti dall'utente, costruiti tramite la PROC FORMAT.

228

Di norma, la TABULATE non prende in considerazione livelli mancanti, cio se una variabile di classe contiene dei valori mancanti, questi normalmente non compariranno in tabella. Affinch i livelli mancanti possano essere presi in considerazione, occorrer specificare l'opzione MISSING al momento del richiamo della TABULATE. La TABULATE considera di classe quelle variabili che sono elencate in una dichiarazione CLASS. La TABULATE usa le variabili di classe per definire delle categorie, ciascuna delle quali rappresenta un valore della variabile di classe. Esempi di variabili di classe: reparto et sesso mese ecc.. Le variabili di analisi devono essere esclusivamente di tipo numerico (aventi valori discreti o continui). La TABULATE considera di analisi quelle variabili che sono elencate in una dichiarazione VAR. I valori delle variabili di analisi sono utilizzati per calcolare statistiche descrittive (es.: media, somma, minimo, varianza, ecc.). Esempi di variabili di analisi: et stipendio votazione scolastica quantit di un farmaco somministrato ecc. La sintassi della PROC TABULATE la seguente:
PROC TABULATE DATA=<archivio_SAS> [opzioni]; CLASS <lista di variabili>; VAR <lista di variabili>; LABEL variabile='etichetta' ...; FORMAT <variabile> <formato.> <variabile> <formato.>.......; BY <variabili di ordinamento>; FREQ <variabile-peso di ciascuna osservazione>; WEIGHT <variabile-peso di variabili di analisi>; TABLE [[<espress.-dimens.pagina>,] <espress.-dimens.riga>,] <espress.-dimens.colonna>/ [opzioni]; KEYLABEL <parola-chiave-di-statistica>='etichetta';

Le dichiarazioni PROC, CLASS o VAR e TABLE devono essere sempre specificate, mentre le altre sono opzionali. 229

Controllo della forma fisica della tabella La dichiarazione TABLE usata per indicare la forma ed i contenuti della tabella da costruire; per questo si usa una sintassi del tipo: TABLE [[<espressione <espressione 3>; 1>,] <espressione 2>,]

dove: espressione 1, espressione 2 e espressione 3, rappresentano ciascuna dimensione della tabella. Nella dichiarazione TABLE, espressione 1 (dimensione pagina) ed espressione 2 (dimensione riga) possono anche mancare, ma espressione 3 deve essere sempre presente. Una espressione si compone di: operatori ed operandi; gli operandi possono essere: variabili di classe, di analisi o parole chiave rappresentanti richieste di statistiche da calcolare. Gli operatori usabili sono: , virgola: separa una dimensione dall'altra; * asterisco: indica una gerarchia o una nidificazione tra variabili; spazio: indica la concatenazione di due o pi variabili; () parentesi: indica un raggruppamento di variabili; <> parentesi acute: specificano la definizione del denominatore nel calcolo delle percentuali; = uguale: assegna una etichetta alla statistica o alla variabile precedente; F= assegna un formato alle statistiche. Per rendere pi chiara la trattazione proviamo, a titolo d'esempio, a realizzare alcune tabelle mediante l'uso di varie dichiarazioni TABLE, prendendo come esempio un archivio SAS avente le seguenti variabili: AZIENDA, REPARTO, MESE. Si supponga che tali variabili possano assumere i valori come mostrato in figura 6.23:
Variabile AZIENDA REPARTO MESE Valori A, B 1, 2 GEN, FEB

Figura 6.23: Associazione variabile-valore 230

Una dichiarazione TABLE come quella presente nel programma seguente, richiede una tabella avente una sola dimensione: colonna. Ciascun valore della variabile AZIENDA sar posizionato in colonne adiacenti, come mostrato in figura 6.24.
PROC TABULATE; CLASS AZIENDA; TABLE AZIENDA;
-------------------------| AZIENDA | |------------------------| | A | B | |------------------------| | | | --------------------------

Figura 6.24: Uscita della PROC TABULATE Nella dichiarazione TABLE del programma seguente, le due variabili AZIENDA e REPARTO sono separate da un operatore virgola (,); verr prodotta una tabella a due dimensioni: riga e colonna. I valori della prima variabile formano le righe, quelle della seconda le colonne, come mostrato in figura 6.25.
PROC TABULATE; CLASS AZIENDA REPARTO; TABLE AZIENDA, REPARTO;
---------------------------------| REPARTO | |--------------------------------| | | 1 | 2 | |-------+-----------+------------| |AZIENDA| | | |-------+ | | | A | | | |-------+-----------+------------| | B | | | ----------------------------------

Figura 6.25: Uscita della PROC TABULATE Il programma seguente mostra una dichiarazione TABLE avente tre variabili separate da operatori virgola (,); in questo caso, verr prodotta una tabella per ogni valore della prima variabile (dimensione pagina). I valori della seconda e terza variabile formeranno, rispettivamente, le righe e le colonne di ciascuna tabella.
PROC TABULATE; CLASS AZIENDA REPARTO MESE; TABLE AZIENDA, REPARTO, MESE;

231

I risultati di questo programma sono illustrati dalla figura 6.26.


AZIENDA A ---------------------------------| MESE | |--------------------------------| | | GEN | FEB | |-------+-----------+------------| |REPARTO| | | |-------+ | | | 1 | | | |-------+-----------+------------| | 2 | | | ----------------------------------

AZIENDA B ---------------------------------| MESE | |--------------------------------| | | GEN | FEB | |-------+-----------+------------| |REPARTO| | | |-------+ | | | 1 | | | |-------+-----------+------------| | 2 | | | ----------------------------------

Figura 6.26: Uscita della PROC TABULATE La nidificazione (gerarchia) tra variabili viene controllata dall'operatore asterisco (*); la dichiarazione TABLE del programma successivo esprime una gerarchia tra le variabili AZIENDA e REPARTO.
PROC TABULATE; CLASS AZIENDA REPARTO; TABLE AZIENDA*REPARTO;

I risultati di questo programma sono illustrati dalla figura 6.27.


------------------------| AZIENDA | |-----------------------| | A | B | |-----------+-----------| | REPARTO | REPARTO | |-----------+-----------| | 1 | 2 | 1 | 2 | |-----+-----+-----+-----| | | | | | | | | | | -------------------------

Figura 6.27: Uscita della PROC TABULATE La dichiarazione TABLE del programma seguente mostra una concatenazione tra le variabili AZIENDA e REPARTO. 232

La concatenazione di variabili viene espressa interponendo l'operatore spazio ( ) tra esse. La figura 6.28 mostra i risultati di questo programma.
PROC TABULATE; CLASS AZIENDA REPARTO; TABLE AZIENDA REPARTO;

------------------------------------| AZIENDA | REPARTO | |-----------------------+-----------| | A | B | 1 | 2 | |-----------+-----------+-----+-----| | | | | | | | | | |


-----------------------------------------

Figura 6.28: Uscita della PROC TABULATE Gli esempi di PROC TABULATE che seguono faranno uso dei dati contenuti nell'archivio VENDITE rappresentato in figura 6.29.
OBS NOMERAP 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Artale Artale Artale Artale Artale Artale Artale Artale Artale Banti Banti Banti Banti Banti Banti Banti Banti Banti DATAVE ARTICOLO Cartucce Scheda I/O Interfaccia GPX Video a colori Package "Multiplan" Video bianco-nero Pacco carta A4 Pennarelli plotter Cartucce Interfaccia KSP Package "Astra" Video a colori Pacco di carta A3 Package "Multiplan" Scheda I/O Scheda I/O Pennarelli plotter Pacco carta A4 NUMERO 10 1 2 1 1 1 20 10 20 1 1 3 30 1 1 2 20 10 COSTO TOTALE MESE GIORNO 1 1 1 2 2 2 3 3 3 1 1 2 2 2 2 3 3 3 7 2 2 6 7 3 3 4 3 7 7 5 6 2 2 3 2 7 03/01/87 05/01/87 05/01/87 13/02/87 14/02/87 17/02/87 03/03/87 04/03/87 10/03/87 03/01/87 03/01/87 05/02/87 13/02/87 16/02/87 16/02/87 10/03/87 16/03/87 21/03/87 5000 50000 150000 150000 400000 800000 200000 200000 180000 180000 150000 150000 4000 80000 5700 57000 5000 100000 275000 275000 400000 400000 600000 1800000 5000 150000 180000 180000 150000 150000 150000 300000 5700 114000 4000 40000

Figura 6.29: Archivio usato per gli esempi di PROC TABULATE Esempio: produrre una tabella che mostri il numero di vendite effettuate da ciascun rappresentante. La figura 6.30 mostra i risultati del programma seguente.
PROC TABULATE DATA=VENDITE; CLASS NOMERAP; TABLE NOMERAP; RUN;

Se non viene usata una dichiarazione VAR, la statistica fornita nella tabella, per definizione, N, cio la frequenza di ciascun valore 233

delle variabili presenti nella TABLE. Affinch sia possibile calcolare somme, medie e altre statistiche, necessaria la presenza della dichiarazione VAR nel programma.
--------------------------| NOMERAP | |-------------------------| | Artale | Banti | |------------+------------| | N | N | |------------+------------| | 9.00| 9.00| ---------------------------

Figura 6.30: Uscita della PROC TABULATE Ad esempio, per analizzare, il totale di unit vendute: aggiungere la variabile di analisi NUMERO nella dichiarazione VAR e usarla nella dichiarazione TABLE per calcolare il totale unit vendute; in mancanza di ulteriori specifiche viene generata la statistica SUM (somma) per ciascuna variabile di analisi presente nella dichiarazione TABLE. Il programma seguente realizza quanto richiesto e la figura 6.31 mostra i risultati relativi.
PROC TABULATE DATA=VENDITE; CLASS NOMERAP; VAR NUMERO; TABLE NOMERAP*NUMERO*SUM /* EQUIVALE A: TABLE NOMERAP*NUMERO RUN;

*/;

--------------------------| NOMERAP | |-------------------------| | Artale | Banti | |------------+------------| | NUMERO | NUMERO | |------------+------------| | SUM | SUM | |------------+------------| | 66.00| 69.00| ---------------------------

Figura 6.31: Uscita della PROC TABULATE L'operatore di nidificazione "*" (asterisco) pu essere usato per nidificare una variabile di classe all'interno di un'altra allo scopo di ottenere maggiori dettagli dalla lettura della tabella. Esempio: produrre una tabella che mostri il totale delle unit vendute in ciascun mese da ciascun rappresentante. Il programma seguente realizza quanto richiesto e la figura 6.32 mostra i risultati relativi.

234

PROC TABULATE DATA=VENDITE; CLASS NOMERAP MESE; VAR NUMERO; TABLE MESE*NOMERAP*NUMERO*SUM; /*o TABLE*NOMERAP*NUMERO*/ /* CLASSE*CLASSE*ANALISI*STATISTICA */ RUN;
------------------------------------------------------------------------------| MESE | |-----------------------------------------------------------------------------| | 1 | 2 | 3 | |-------------------------+-------------------------+-------------------------| | NOMERAP | NOMERAP | NOMERAP | |-------------------------+-------------------------+-------------------------| | Artale | Banti | Artale | Banti | Artale | Banti | |------------+------------+------------+------------+------------+------------| | NUMERO | NUMERO | NUMERO | NUMERO | NUMERO | NUMERO | |------------+------------+------------+------------+------------+------------| | SUM | SUM | SUM | SUM | SUM | SUM | |------------+------------+------------+------------+------------+------------| | 13.00| 2.00| 3.00| 35.00| 50.00| 32.00| -------------------------------------------------------------------------------

Figura 6.32: Uscita della PROC TABULATE Mediante l'opzione FORMAT possibile modificare la forma della tabella ed, in particolare, possibile: definire l'ampiezza della cella; definire il formato dei valori delle celle. Esempio: rendere di 8 posizioni l'ampiezza di ogni cella della tabella. Il programma seguente realizza quanto richiesto e la figura 6.33 mostra i risultati relativi.
PROC TABULATE DATA=VENDITE FORMAT=8.; CLASS NOMERAP MESE; VAR NUMERO; TABLE MESE*NOMERAP*NUMERO /* CLASSE*CLASSE*ANALISI */ ; RUN;

------------------------------------------------------| MESE | |-----------------------------------------------------| | 1 | 2 | 3 | |-----------------+-----------------+-----------------| | NOMERAP | NOMERAP | NOMERAP | |-----------------+-----------------+-----------------| | Artale | Banti | Artale | Banti | Artale | Banti | |--------+--------+--------+--------+--------+--------| | NUMERO | NUMERO | NUMERO | NUMERO | NUMERO | NUMERO | |--------+--------+--------+--------+--------+--------| | SUM | SUM | SUM | SUM | SUM | SUM | |--------+--------+--------+--------+--------+--------| | 13| 2| 3| 35| 50| 32| -------------------------------------------------------

Figura 6.33: Uscita della PROC TABULATE 235

Possiamo apportare ulteriori modifiche alla tabella di figura 6.33. Ad esempio: ponendo la variabile mese nella dimensione di riga; controllando il numero di caratteri usati per costruire la colonna dei titoli di ciascuna riga, mediante il parametro RTS (Row Title Space). portando a 12 caratteri l'ampiezza della cella. Il risultato riportato in figura 6.34.
PROC TABULATE DATA=VENDITE FORMAT=12.; CLASS NOMERAP MESE; VAR NUMERO; TABLE MESE,NOMERAP*NUMERO/RTS=7 /* CLASSE,CLASSE*ANALISI*/; RUN;
--------------------------------| | NOMERAP | | |-------------------------| | | Artale | Banti | | |------------+------------| | | NUMERO | NUMERO | | |------------+------------| | | SUM | SUM | |-----+------------+------------| |MESE | | | |-----| | | |1 | 13| 2| |-----+------------+------------| |2 | 3| 35| |-----+------------+------------| |3 | 50| 32| ---------------------------------

Figura 6.34: Uscita della PROC TABULATE E' possibile concatenare variabili tra loro, per aggiungere ulteriori informazioni alla tabella. Esempio: mostrare, nella stessa tabella, il numero di vendite effettuate da ciascun rappresentante, ripartite prima per mese e poi per giorno della settimana (2=Luned, 3=Marted, ecc.). Il programma seguente realizza quanto richiesto e la figura 6.35 mostra i risultati relativi.
PROC TABULATE DATA=VENDITE FORMAT=12.; CLASS NOMERAP MESE GIORNO; VAR NUMERO; TABLE MESE GIORNO, NOMERAP*NUMERO /* CLASSE CLASSE, CLASSE*ANALISI

*/;

Si possono totalizzare i valori presenti nelle celle utilizzando la variabile di classe speciale ALL, la quale genera un totale per la variabile che la precede nella dichiarazione TABLE. 236

----------------------------------------------------------| | NOMERAP | | |-------------------------| | | Artale | Banti | | |------------+------------| | | NUMERO | NUMERO | | |------------+------------| | | SUM | SUM | |-------------------------------+------------+------------| |MESE | | | |-------------------------------| | | |1 | 13| 2| |-------------------------------+------------+------------| |2 | 3| 35| |-------------------------------+------------+------------| |3 | 50| 32| |-------------------------------+------------+------------| |GIORNO | | | |-------------------------------| | | |2 | 3| 22| |-------------------------------+------------+------------| |3 | 41| 2| |-------------------------------+------------+------------| |4 | 10| .| |-------------------------------+------------+------------| |5 | .| 3| |-------------------------------+------------+------------| |6 | 1| 30| |-------------------------------+------------+------------| |7 | 11| 12| -----------------------------------------------------------

Figura 6.35: Uscita della PROC TABULATE Esempio: aggiungere alla tabella di figura 6.35 due righe di totale, per le variabili GIORNO e MESE.
TITLE 'LA CATEGORIA ALL'; PROC TABULATE DATA=VENDITE FORMAT=12.; CLASS NOMERAP MESE GIORNO; VAR NUMERO; TABLE MESE ALL GIORNO ALL, NOMERAP*NUMERO /* CLASSE ALL CLASSE ALL, CLASSE*ANALISI */ ; RUN;

L'uscita viene mostrata in figura 6.36. Dall'esame della tabella si nota che la "non vendita" di prodotti in un mese o in un giorno della settimana, viene segnalata dalla presenza di un valore mancante nella cella corrispondente (esempio: NOMERAP=Banti, GIORNO=4). La categoria ALL pu essere usata contemporaneamente nella dimensione riga e colonna.

237

LA CATEGORIA ALL ----------------------------------------------------------| | NOMERAP | | |-------------------------| | | Artale | Banti | | |------------+------------| | | NUMERO | NUMERO | | |------------+------------| | | SUM | SUM | |-------------------------------+------------+------------| |MESE | | | |-------------------------------| | | |1 | 13| 2| |-------------------------------+------------+------------| |2 | 3| 35| |-------------------------------+------------+------------| |3 | 50| 32| |-------------------------------+------------+------------| |ALL | 66| 69| |-------------------------------+------------+------------| |GIORNO | | | |-------------------------------| | | |2 | 3| 22| |-------------------------------+------------+------------| |3 | 41| 2| |-------------------------------+------------+------------| |4 | 10| .| |-------------------------------+------------+------------| |5 | .| 3| |-------------------------------+------------+------------| |6 | 1| 30| |-------------------------------+------------+------------| |7 | 11| 12| |-------------------------------+------------+------------| |ALL | 66| 69| -----------------------------------------------------------

Figura 6.36: Uscita della PROC TABULATE Esempio: aggiungere alla tabella di figura 6.36 una colonna che mostri i totali di riga. Il programma seguente realizza quanto richiesto, e la figura 6.37 mostra i risultati relativi.
TITLE 'LA CATEGORIA ALL'; PROC TABULATE DATA=VENDITE FORMAT=12.; CLASS NOMERAP MESE GIORNO; VAR NUMERO; TABLE MESE ALL GIORNO ALL, NOMERAP*NUMERO ALL*NUMERO; RUN;

Come rendere le tabelle pi leggibili Per ottenere tabelle pi chiare e leggibili, si possono utilizzare formati che decodifichino i valori delle variabili prima del loro sistemazione nella tabella, ed etichette che rendano pi espliciti i nomi delle variabili.

238

LA CATEGORIA ALL -----------------------------------------------------------------------| | NOMERAP | | | |-------------------------| | | | Artale | Banti | ALL | | |------------+------------+------------| | | NUMERO | NUMERO | NUMERO | | |------------+------------+------------| | | SUM | SUM | SUM | |-------------------------------+------------+------------+------------| |MESE | | | | |-------------------------------| | | | |1 | 13| 2| 15| |-------------------------------+------------+------------+------------| |2 | 3| 35| 38| |-------------------------------+------------+------------+------------| |3 | 50| 32| 82| |-------------------------------+------------+------------+------------| |ALL | 66| 69| 135| |-------------------------------+------------+------------+------------| |GIORNO | | | | |-------------------------------| | | | |2 | 3| 22| 25| |-------------------------------+------------+------------+------------| |3 | 41| 2| 43| |-------------------------------+------------+------------+------------| |4 | 10| .| 10| |-------------------------------+------------+------------+------------| |5 | .| 3| 3| |-------------------------------+------------+------------+------------| |6 | 1| 30| 31| |-------------------------------+------------+------------+------------| |7 | 11| 12| 23| |-------------------------------+------------+------------+------------| |ALL | 66| 69| 135| ------------------------------------------------------------------------

Figura 6.37: Uscita della PROC TABULATE Esempio: rendere pi leggibile la tabella di figura 6.37 utilizzando i nomi dei mesi e dei giorni ed aggiungendo etichette che sostituiscano i nomi delle variabili con diciture pi chiare. Il programma seguente realizza quanto richiesto e la figura 6.38 mostra i risultati relativi.
PROC FORMAT; VALUE MESEFM 1='Gennaio' 2='Febbraio' 3='Marzo'; VALUE GIORNOFM 2='Lunedi''' 3='Martedi''' 4='Mercoledi''' 5='Giovedi''' 6='Venerdi''' 7='Sabato'; TITLE 'LA CATEGORIA ALL'; PROC TABULATE DATA=VENDITE FORMAT=8.; CLASS NOMERAP MESE GIORNO; VAR NUMERO; FORMAT MESE MESEFM. GIORNO GIORNOFM.; LABEL MESE='MESE DELLA VENDITA' GIORNO='GIORNO DELLA SETTIMANA' NOMERAP='NOME DEL RAPPRESENTANTE'; TABLE MESE ALL GIORNO ALL NOMERAP*NUMERO ALL*NUMERO; RUN;

239

LA CATEGORIA ALL -----------------------------------------------------------| | NOME DEL | | | | RAPPRESENTANTE | | | |-----------------| | | | Artale | Banti | ALL | | |--------+--------+--------| | | NUMERO | NUMERO | NUMERO | | |--------+--------+--------| | | SUM | SUM | SUM | |-------------------------------+--------+--------+--------| |MESE DELLA VENDITA | | | | |-------------------------------| | | | |Gennaio | 13| 2| 15| |-------------------------------+--------+--------+--------| |Febbraio | 3| 35| 38| |-------------------------------+--------+--------+--------| |Marzo | 50| 32| 82| |-------------------------------+--------+--------+--------| |ALL | 66| 69| 135| |-------------------------------+--------+--------+--------| |GIORNO DELLA SETTIMANA | | | | |-------------------------------| | | | |Lunedi' | 3| 22| 25| |-------------------------------+--------+--------+--------| |Martedi' | 41| 2| 43| |-------------------------------+--------+--------+--------| |Mercoledi' | 10| .| 10| |-------------------------------+--------+--------+--------| |Giovedi' | .| 3| 3| |-------------------------------+--------+--------+--------| |Venerdi' | 1| 30| 31| |-------------------------------+--------+--------+--------| |Sabato | 11| 12| 23| |-------------------------------+--------+--------+--------| |ALL | 66| 69| 135| ------------------------------------------------------------

Figura 6.38: Uscita della PROC TABULATE Per cambiare i nomi delle statistiche generate dalla procedura, ad esempio, per tradurli in italiano, si pu usare la dichiarazione KEYLABEL. Esempio: personalizzare ulteriormente la tabella mostrata in figura 6.38, in particolare cambiando i nomi standard delle statistiche generate dalla procedura e la categoria ALL, con nomi scelti a piacere. Il risultato del programma seguente mostrato in figura 6.39.
TITLE 'USO DI FORMATI, LABEL E KEYLABEL'; PROC TABULATE DATA=VENDITE FORMAT=10.; CLASS NOMERAP MESE GIORNO; VAR NUMERO; FORMAT MESE MESEFM. GIORNO GIORNOFM.; LABEL MESE='MESE DELLA VENDITA' GIORNO='GIORNO DELLA SETTIMANA' NOMERAP='NOME DEL RAPPRESENTANTE'; KEYLABEL ALL='* TOTALE *' SUM=' '; TABLE MESE ALL GIORNO ALL,NOMERAP*NUMERO ALL*NUMERO; RUN;

240

USO DI FORMATI, LABEL E KEYLABEL -----------------------------------------------------------------| | NOME DEL | | | | RAPPRESENTANTE | | | |---------------------| | | | Artale | Banti |* TOTALE *| | |----------+----------+----------| | | NUMERO | NUMERO | NUMERO | |-------------------------------+----------+----------+----------| |MESE DELLA VENDITA | | | | |-------------------------------| | | | |Gennaio | 13| 2| 15| |-------------------------------+----------+----------+----------| |Febbraio | 3| 35| 38| |-------------------------------+----------+----------+----------| |Marzo | 50| 32| 82| |-------------------------------+----------+----------+----------| |* TOTALE * | 66| 69| 135| |-------------------------------+----------+----------+----------| |GIORNO DELLA SETTIMANA | | | | |-------------------------------| | | | |Lunedi' | 3| 22| 25| |-------------------------------+----------+----------+----------| |Martedi' | 41| 2| 43| |-------------------------------+----------+----------+----------| |Mercoledi' | 10| .| 10| |-------------------------------+----------+----------+----------| |Giovedi' | .| 3| 3| |-------------------------------+----------+----------+----------| |Venerdi' | 1| 30| 31| |-------------------------------+----------+----------+----------| |Sabato | 11| 12| 23| |-------------------------------+----------+----------+----------| |* TOTALE * | 66| 69| 135| ------------------------------------------------------------------

Figura 6.39: Uscita della PROC TABULATE Uso avanzato della PROC TABULATE La parte seguente illustra come formattare e personalizzare le tabelle con l'uso, nella dichiarazione TABLE, di etichette e di formati scelti dall'utente: nome-variabile=etichetta, permette di stampare nomi personalizzati delle variabili; questa assegnazione risulta temporanea, cio valida ai soli fini della tabella in questione; anche la dichiarazione LABEL permette di assegnare una etichetta ad una variabile, ma in questo caso l'associazione variabile-etichetta viene considerata valida per tutte le tabelle prodotte dalle dichiarazioni TABLE della procedura che fanno riferimento a quella variabile. nome-statistica=etichetta,permette di stampare nomi personalizzati delle statistiche; per questa personalizzazione resta valido quanto detto per l'assegnazione nomevariabile=, cambiando nelle frasi la parola LABEL con KEYLABEL. Esempio: usare le opzioni precedenti per personalizzare i nomi delle statistiche e delle variabili della tabella di figura 6.39. Il programma 241

seguente realizza quanto richiesto e la figura 6.40 mostra i risultati relativi.


TITLE 'Uso di nome-variabile=opzione'; PROC TABULATE DATA=VENDITE; CLASS NOMERAP MESE GIORNO; VAR NUMERO; FORMAT MESE MESEFM. GIORNO GIORNOFM.; TABLE MESE='MESE' ALL='TOTALE MENSILE' GIORNO='GIORNO' ALL='TOTALI DI COLONNA', NOMERAP='NOME ADDETTO ALLE VENDITE' *NUMERO='Unita''vendute' ALL='TOTALI DI RIGA'*NUMERO='UNITA'''; RUN;
Uso di nome-variabile=opzione -----------------------------------------------------------------------| |NOME ADDETTO ALLE VENDITE| | | |-------------------------| | | | Artale | Banti | TOTALI DI | | |------------+------------| RIGA | | | Unita' | Unita' |------------| | | vendute | vendute | UNITA' | | |------------+------------+------------| | | SUM | SUM | SUM | |-------------------------------+------------+------------+------------| |MESE | | | | |-------------------------------| | | | |Gennaio | 13.00| 2.00| 15.00| |-------------------------------+------------+------------+------------| |Febbraio | 3.00| 35.00| 38.00| |-------------------------------+------------+------------+------------| |Marzo | 50.00| 32.00| 82.00| |-------------------------------+------------+------------+------------| |TOTALE MENSILE | 66.00| 69.00| 135.00| |-------------------------------+------------+------------+------------| |GIORNO | | | | |-------------------------------| | | | |Lunedi' | 3.00| 22.00| 25.00| |-------------------------------+------------+------------+------------| |Martedi' | 41.00| 2.00| 43.00| |-------------------------------+------------+------------+------------| |Mercoledi' | 10.00| .| 10.00| |-------------------------------+------------+------------+------------| |Giovedi' | .| 3.00| 3.00| |-------------------------------+------------+------------+------------| |Venerdi' | 1.00| 30.00| 31.00| |-------------------------------+------------+------------+------------| |Sabato | 11.00| 12.00| 23.00| |-------------------------------+------------+------------+------------| |TOTALI DI COLONNA | 66.00| 69.00| 135.00|
------------------------------------------------------------------------------------------------

Figura 6.40: Uscita della PROC TABULATE Dimensionamento delle colonne L'opzione F= permette di attribuire un formato ai valori che verranno stampati in tabella e pu essere associato a qualsiasi variabile o gruppo di variabili appartenenti alle dimensioni: pagina, riga o colonna. F= permette inoltre di variare la larghezza delle singole celle, indipendentemente da quanto stato stabilito dall'opzione generale FORMAT= della dichiarazione PROC TABULATE. 242

Esempio: facendo riferimento alla tabella mostrata in figura 6.40, dimensionare le celle di NOMERAP di 6 caratteri quelle della categoria ALL di 10 caratteri. Il programma seguente realizza quanto richiesto e la figura 6.41 mostra i risultati relativi.
TITLE 'Uso dell''opzione F='; PROC TABULATE DATA=VENDITE; CLASS NOMERAP MESE GIORNO; VAR NUMERO; FORMAT MESE MESEFM. GIORNO GIORNOFM.; TABLE MESE ALL GIORNO ALL, NOMERAP*NUMERO*F=6. ALL*NUMERO*F=10.; RUN;
Uso dell'opzione F= ---------------------------------------------------------| | NOMERAP | | | |-------------| | | |Artale|Banti | ALL | | |------+------+----------| | |NUMERO|NUMERO| NUMERO | | |------+------+----------| | | SUM | SUM | SUM | |-------------------------------+------+------+----------| |MESE | | | | |-------------------------------| | | | |Gennaio | 13| 2| 15| |-------------------------------+------+------+----------| |Febbraio | 3| 35| 38| |-------------------------------+------+------+----------| |Marzo | 50| 32| 82| |-------------------------------+------+------+----------| |ALL | 66| 69| 135| |-------------------------------+------+------+----------| |GIORNO | | | | |-------------------------------| | | | |Lunedi' | 3| 22| 25| |-------------------------------+------+------+----------| |Martedi' | 41| 2| 43| |-------------------------------+------+------+----------| |Mercoledi' | 10| .| 10| |-------------------------------+------+------+----------| |Giovedi' | .| 3| 3| |-------------------------------+------+------+----------| |Venerdi' | 1| 30| 31| |-------------------------------+------+------+----------| |Sabato | 11| 12| 23| |-------------------------------+------+------+----------| |ALL | 66| 69| 135| ----------------------------------------------------------

Figura 6.41: Uscita della PROC TABULATE Esempio: personalizzare ulteriormente la tabella di figura 6.41 combinando le opzioni nome-variabile=, nome-statistica= ed F=.

243

Il programma seguente realizza quanto richiesto e la figura 6.42 mostra i risultati relativi.
TITLE 'Uso dell''opzione F= e nome-variabile='; PROC TABULATE DATA=VENDITE; CLASS NOMERAP MESE GIORNO; VAR NUMERO; FORMAT MESE MESEFM. GIORNO GIORNOFM.; TABLE MESE='MESE' ALL='TOTALE MENSILE' GIORNO='GIORNO DELLA SETTIMANA' ALL='TOTALE PER GIORNO', NOMERAP='NOME ADDETTO'* NUMERO='NUMERO PEZZI'*SUM=' '*F=8. ALL='TOTALE DI COLONNA'* NUMERO='UNITA'''*SUM=' '*F=10.; RUN;
Uso dell'opzione F= e nome-variabile= -------------------------------------------------------------| | NOME ADDETTO | | | |-----------------| | | | Artale | Banti |TOTALE DI | | |--------+--------| COLONNA | | | NUMERO | NUMERO |----------| | | PEZZI | PEZZI | UNITA' | |-------------------------------+--------+--------+----------| |MESE | | | | |-------------------------------| | | | |Gennaio | 13| 2| 15| |-------------------------------+--------+--------+----------| |Febbraio | 3| 35| 38| |-------------------------------+--------+--------+----------| |Marzo | 50| 32| 82| |-------------------------------+--------+--------+----------| |TOTALE MENSILE | 66| 69| 135| |-------------------------------+--------+--------+----------| |GIORNO DELLA SETTIMANA | | | | |-------------------------------| | | | |Lunedi' | 3| 22| 25| |-------------------------------+--------+--------+----------| |Martedi' | 41| 2| 43| |-------------------------------+--------+--------+----------| |Mercoledi' | 10| .| 10| |-------------------------------+--------+--------+----------| |Giovedi' | .| 3| 3| |-------------------------------+--------+--------+----------| |Venerdi' | 1| 30| 31| |-------------------------------+--------+--------+----------| |Sabato | 11| 12| 23| |-------------------------------+--------+--------+----------| |TOTALE PER GIORNO | 66| 69| 135| --------------------------------------------------------------

Figura 6.42: Uscita della PROC TABULATE L'opzione FORMCHAR= pu essere usata per ridefinire i caratteri usabili per costruire la griglia della tabella. All'interno degli apici vanno specificati gli undici caratteri utilizzati dalla procedura nel seguente ordine:

244

barra verticale; barra orizzontale; intersezione alta sinistra; intersezione alta media; intersezione alta destra; intersezione media sinistra; intersezione media media (croce); intersezione media destra; intersezione bassa sinistra; intersezione bassa media; intersezione bassa destra. Il valore di FORMCHAR assunto in mancanza di specifiche :
FORMCHAR='|----|+|---'

possibile variare anche solo parte dei caratteri di FORMCHAR come si pu vedere nel seguente caso dove si cambiano solo il primo carattere e il settimo (tra 1 e 7 c' uno spazio):
FORMCHAR(1 7)='|+'

La stringa pu essere data anche in esadecimale. La seguente stringa consigliata per le stampanti IBM 1403, IBM 3211 e IBM 3203-5 con una catena di stampa TN:
FORMCHAR='4FBFACBFBC4F8F4FABBFBB'X

Esempio: utilizzare la FORMCHAR= per cambiare i caratteri impiegati per formare la griglia della tabella. Il programma seguente realizza quanto richiesto e la figura 6.43 mostra i risultati relativi.
TITLE 'SENZA GRIGLIA'; PROC TABULATE DATA=VENDITE FORMCHAR=' CLASS NOMERAP MESE GIORNO; VAR NUMERO; FORMAT MESE MESEFM. GIORNO GIORNOFM.; TABLE GIORNO='GIORNO DELLA SETTIMANA' ALL='TOTALE PER MESE', MESE='MESE' ALL='TOTALE PER GIORNO'; RUN; ';

245

SENZA GRIGLIA

MESE TOTALE PER GIORNO N

Gennaio N GIORNO DELLA SETTIMANA Lunedi' Martedi' Mercoledi' Giovedi' Venerdi' Sabato TOTALE PER MESE 2.00 . . . . 3.00 5.00

Febbraio N

Marzo N

2.00 1.00 . 1.00 2.00 1.00 7.00

1.00 3.00 1.00 . . 1.00 6.00

5.00 4.00 1.00 1.00 2.00 5.00 18.00

Figura 6.43: Uscita della PROC TABULATE

Altre statistiche utilizzabili con la TABULATE Altre statistiche utilizzabili con la TABULATE sono: N NMISS MEAN STD MIN MAX RANGE SUM PCTN il numero di osservazioni con valori non "missing" per una variabile di analisi; il numero di osservazioni con valori "missing" per una variabile di analisi; media; deviazione standard; valore minimo; valore massimo; intervallo di tra il minimo e il massimo; somma; percentuale di frequenze; indica la percentuale che la frequenza riportata in una cella della tabella rappresenta rispetto al totale delle frequenze di una classe o sottoclasse;

PCTSUM percentuale di somma; indica la percentuale che la somma di una variabile di analisi in una cella rappresenta rispetto alla sommatoria di una classe o sottoclasse.

246

Calcolo di percentuali (uso della PCTN) Esempio: produrre una tabella che mostri come si distribuiscono in percentuale, per mese e per venditore, le osservazioni dell'archivio mostrato in figura 6.29. Il programma che segue produce la tabella mostrata in figura 6.43.1. Si noti, ad esempio, che il valore 16.67 posto nella cella all'incrocio della riga "Gennaio" con la colonna "Artale", rappresenta la percentuale delle osservazioni relative alle vendite effettuate dal Sig. Artale nel mese di Gennaio (3) rispetto al numero totale di osservazioni dell'archivio in questione (18).
PROC FORMAT; VALUE MESEFM

1='Gennaio' 2='Febbraio' 3='Marzo'; TITLE 'PERCENTUALE SUL TOTALE DELLE OSSERVAZIONI'; PROC TABULATE DATA=VENDITE; FORMAT MESE MESEFM.; CLASS NOMERAP MESE; TABLE MESE ALL, NOMERAP*PCTN*F=8.2; RUN;

PERCENTUALE SUL TOTALE DELLE OSSERVAZIONI -----------------------------------| | NOMERAP | | |-----------------| | | Artale | Banti | | |--------+--------| | | PCTN | PCTN | |----------------+--------+--------| |MESE | | | |----------------| | | |Gennaio | 16.67| 11.11| |----------------+--------+--------| |Febbraio | 16.67| 22.22| |----------------+--------+--------| |Marzo | 16.67| 16.67| |----------------+--------+--------| |ALL | 50.00| 50.00| ------------------------------------

Figura 6.43.1: Uscita della PROC TABULATE

Calcolo di percentuali (uso della PCTSUM) Esempio: produrre una tabella che mostri il numero di unit vendute da ciascun rappresentante per ciascun mese e la relativa percentuale rispetto al totale delle vendite effettuate. L'esercizio svolto in due modi diversi.

247

Le due TABLE presenti nel programma seguente realizzano quanto richiesto e le figure 6.44.1 e 6.44.2 mostrano le tabelle ottenute. Questo il pi semplice modo di richiedere le percentuali e, in questo caso, ciascuna percentuale di cella riferita al numero totale dei pezzi venduti da tutti i venditori (66+69=135).
TITLE 'Percentuale sul totale'; PROC TABULATE DATA=VENDITE FORMAT=8.0; CLASS NOMERAP MESE; VAR NUMERO; TABLE MESE ALL, NOMERAP*NUMERO*SUM NOMERAP*NUMERO*PCTSUM; /* oppure TABLE MESE ALL, NOMERAP*NUMERO * (SUM PCTSUM); */ TABLE MESE ALL, NOMERAP*NUMERO*(SUM PCTSUM); RUN;
Percentuale sul totale --------------------------------------------------------------------| | | | | | | |MESE |1 | NOMERAP | NOMERAP | | |-----------------+-----------------| | Artale | Banti | Artale | Banti |--------+--------+--------+--------| | NUMERO | NUMERO | NUMERO | NUMERO | |--------+--------+--------+--------| | | | SUM | | | 13| SUM | PCTSUM | PCTSUM | | | 2| | | 10| | | 1|

|-------------------------------+--------+--------+--------+--------| |-------------------------------|

|-------------------------------+--------+--------+--------+--------| |2 |3 |ALL | | | 3| 50| 66| 35| 32| 69| 2| 37| 49| 26| 24| 51| |-------------------------------+--------+--------+--------+--------| |-------------------------------+--------+--------+--------+--------|

---------------------------------------------------------------------

Figura 6.44.1: Uscita della PROC TABULATE Per calcolare una percentuale rispetto al totale, riferito ad una classe o sottoclasse, di una variabile di analisi si deve indicare la variabile denominatore accanto alla parola chiave PCTSUM, inserendola tra i caratteri < >. Denominatore deve essere una variabile di classe.

248

Esempio: produrre una tabella che mostri la percentuale del numero di vendite effettuate da ciascun rappresentante in ciascun mese, rispetto al totale del numero di vendite da lui effettuate nei tre mesi. L'esercizio svolto in due modi diversi.
Percentuale sul totale --------------------------------------------------------------------| | | | | | | |MESE |1 | | | Artale NUMERO NOMERAP | | Banti NUMERO | | | |-----------------------------------| |-----------------+-----------------|

|-----------------+-----------------| | | | SUM | PCTSUM | | | 13| | | 10| SUM | PCTSUM | | | 2| | | 1|

|-------------------------------+--------+--------+--------+--------| |-------------------------------|

|-------------------------------+--------+--------+--------+--------| |2 |3 |ALL | | | 3| 50| 66| 2| 37| 49| 35| 32| 69| 26| 24| 51| |-------------------------------+--------+--------+--------+--------| |-------------------------------+--------+--------+--------+--------|

---------------------------------------------------------------------

Figura 6.44.2: Uscita della PROC TABULATE Le due TABLE presenti nel programma seguente realizzano quanto richiesto e le figure 6.45.1 e 6.45.2 mostrano le rispettive tabelle ottenute. In questo caso si nota, ad esempio, che i 13 pezzi venduti dal Sig. Artale nel mese di Gennaio rappresentano il 20% del totale dei pezzi venduti nei tre mesi di analisi (13+3+50=66). Per quanto concerne le percentuali della tabella si nota, ad esempio, che quella relativa al Sig. Artale (20+5+76=101) supera il valore 100; questo dovuto a problemi di arrotondamento nei calcoli; per eliminare questo inconveniente si pu ricorrere all'uso di un formato numerico con cifre decimali.
TITLE 'Percentuale per mese'; PROC TABULATE DATA=VENDITE FORMAT=8.0; CLASS NOMERAP MESE; VAR NUMERO; FORMAT MESE MESEFM.; TABLE MESE, NOMERAP*NUMERO*SUM NOMERAP*NUMERO*PCTSUM<MESE>; TABLE MESE, NOMERAP*NUMERO*(SUM PCTSUM<MESE>); RUN;

249

Percentuale per mese --------------------------------------------------------------------| | | | | | | |MESE |Gennaio | NOMERAP | NOMERAP | | |-----------------+-----------------| | Artale | Banti | Artale | Banti |--------+--------+--------+--------| | NUMERO | NUMERO | NUMERO | NUMERO | |--------+--------+--------+--------| | | | SUM | | | 13| SUM | PCTSUM | PCTSUM | | | 2| | | 20| | | 3|

|-------------------------------+--------+--------+--------+--------| |-------------------------------|

|-------------------------------+--------+--------+--------+--------| |Febbraio |Marzo | | 3| 50| 35| 32| 5| 76| 51| 46| |-------------------------------+--------+--------+--------+--------| ---------------------------------------------------------------------

Figura 6.45.1: Uscita della PROC TABULATE


Percentuale per mese --------------------------------------------------------------------| | NOMERAP | | |-----------------------------------| | | Artale | Banti | | |-----------------+-----------------| | | NUMERO | NUMERO | | |-----------------+-----------------| | | SUM | PCTSUM | SUM | PCTSUM | |-------------------------------+--------+--------+--------+--------| |MESE | | | | | |-------------------------------| | | | | |Gennaio | 13| 20| 2| 3| |-------------------------------+--------+--------+--------+--------| |Febbraio | 3| 5| 35| 51| |-------------------------------+--------+--------+--------+--------| |Marzo | 50| 76| 32| 46| ---------------------------------------------------------------------

Figura 6.45.2: Uscita della PROC TABULATE Esempio: produrre una tabella che mostri, relativamente a ciascun mese: il numero di vendite effettuate da ciascun rappresentante e la relativa percentuale rispetto al totale delle vendite effettuate nel mese da tutti i rappresentanti. L'esercizio svolto in due modi diversi. Le due TABLE presenti nel programma seguente realizzano quanto richiesto e le tabelle di uscita sono rappresentate nelle figure 6.46.1 e 6.46.2.

250

TITLE 'Percentuale per NOMERAP'; PROC TABULATE DATA=VENDITE FORMAT=8.0; CLASS NOMERAP MESE; VAR NUMERO; FORMAT MESE MESEFM.; TABLE MESE, NOMERAP*NUMERO*SUM NOMERAP*NUMERO*PCTSUM<NOMERAP>; TABLE MESE, NOMERAP*NUMERO*(SUM PCTSUM<NOMERAP>); RUN;

Percentuale per NOMERAP --------------------------------------------------------------------| | NOMERAP | NOMERAP | | |-----------------+-----------------| | | Artale | Banti | Artale | Banti | | |--------+--------+--------+--------| | | NUMERO | NUMERO | NUMERO | NUMERO | | |--------+--------+--------+--------| | | SUM | SUM | PCTSUM | PCTSUM | |-------------------------------+--------+--------+--------+--------| |MESE | | | | | |-------------------------------| | | | | |Gennaio | 13| 2| 87| 13| |-------------------------------+--------+--------+--------+--------| |Febbraio | 3| 35| 8| 92| |-------------------------------+--------+--------+--------+--------| |Marzo | 50| 32| 61| 39| ---------------------------------------------------------------------

Figura 6.46.1: Uscita della PROC TABULATE


Percentuale per NOMERAP --------------------------------------------------------------------| | NOMERAP | | |-----------------------------------| | | Artale | Banti | | |-----------------+-----------------| | | NUMERO | NUMERO | | |-----------------+-----------------| | | SUM | PCTSUM | SUM | PCTSUM | |-------------------------------+--------+--------+--------+--------| |MESE | | | | | |-------------------------------| | | | | |Gennaio | 13| 87| 2| 13| |-------------------------------+--------+--------+--------+--------| |Febbraio | 3| 8| 35| 92| |-------------------------------+--------+--------+--------+--------| |Marzo | 50| 61| 32| 39| ---------------------------------------------------------------------

Figura 6.46.2: Uscita della PROC TABULATE Esempio: per completare le tabelle delle figure 6.45.1 e 6.45.2, aggiungere una riga di totalizzazione (categoria ALL). L'esercizio stato svolto in due modi diversi. Le due dichiarazioni TABLE presenti nel programma precedente realizzano quanto richiesto e le tabelle di uscita sono rappresentate nelle figure 6.47.1 e 6.47.2. 251

TITLE 'Percentuale per mese'; PROC TABULATE DATA=VENDITE FORMAT=8.0; CLASS NOMERAP MESE; VAR NUMERO; FORMAT MESE MESEFM.; TABLE MESE ALL, NOMERAP*NUMERO*SUM NOMERAP*NUMERO*PCTSUM<MESE ALL>; TABLE MESE ALL, NOMERAP*NUMERO*(SUM PCTSUM<MESE ALL>); RUN;
Percentuale per mese --------------------------------------------------------------------| | NOMERAP | NOMERAP | | |-----------------+-----------------| | | Artale | Banti | Artale | Banti | | |--------+--------+--------+--------| | | NUMERO | NUMERO | NUMERO | NUMERO | | |--------+--------+--------+--------| | | SUM | SUM | PCTSUM | PCTSUM | |-------------------------------+--------+--------+--------+--------| |MESE | | | | | |-------------------------------| | | | | |Gennaio | 13| 2| 20| 3| |-------------------------------+--------+--------+--------+--------| |Febbraio | 3| 35| 5| 51| |-------------------------------+--------+--------+--------+--------| |Marzo | 50| 32| 76| 46| |-------------------------------+--------+--------+--------+--------| |ALL | 66| 69| 100| 100| ---------------------------------------------------------------------

Figura 6.47.1: Uscita della PROC TABULATE


Percentuale per mese --------------------------------------------------------------------| | NOMERAP | | |-----------------------------------| | | Artale | Banti | | |-----------------+-----------------| | | NUMERO | NUMERO | | |-----------------+-----------------| | | SUM | PCTSUM | SUM | PCTSUM | |-------------------------------+--------+--------+--------+--------| |MESE | | | | | |-------------------------------| | | | | |Gennaio | 13| 20| 2| 3| |-------------------------------+--------+--------+--------+--------| |Febbraio | 3| 5| 35| 51| |-------------------------------+--------+--------+--------+--------| |Marzo | 50| 76| 32| 46| |-------------------------------+--------+--------+--------+--------| |ALL | 66| 100| 69| 100| ---------------------------------------------------------------------

Figura 6.47.2: Uscita della PROC TABULATE

252

Ulteriori opzioni utilizzabili nella fase di personalizzazione delle tabelle Esistono molte opzioni che permettono una ulteriore personalizzazione delle tabelle prodotte mediante la PROC TABULATE. Alcune di queste trovano posto all'interno della dichiarazione di richiamo della procedura ed altre nella TABLE. Di seguito si riportano quelle di interesse principale per l'utente. Di ciascuna opzione vengono segnalate le modalit d'uso e, scritte in neretto, vengono segnalate quelle che sono assunte dalla procedura in assenza di specifiche (valori di default). Ulteriori opzioni utilizzabili nella dichiarazione PROC MISSING specifica che i valori mancanti delle variabili di classificazione debbono essere considerati validi ai fini della stampa nelle tabelle. Se non viene specificata detta opzione, la procedura esclude dall'analisi quelle osservazioni che presentano variabili di classificazione aventi valore mancante. NOSEPS elimina le linee orizzontali tratteggiate di separazione tra una riga e l'altra della tabella. Detta opzione pu essere usata per compattare verticalmente le tabelle prodotte. ORDER= specifica l'ordine secondo cui verranno presentate le intestazioni nella tabella. ORDER=FREQ indica che le intestazioni saranno evidenziate in funzione della frequenza dei valori delle variabili di classificazione (in ordine decrescente di frequenza). ORDER=DATA indica che l'ordine di lettura dei valori assegnati alle variabili di classificazione sar quello adottato anche nelle tabelle. ORDER=INTERNAL indica che le intestazioni saranno presentate come se avessero subito un procedimento di ordinamento mediante la PROC SORT. ORDER= FORMATTED indica che l'ordinamento delle intestazioni avverr tenendo conto dei valori formattati delle variabili di classificazione. VARDEF= specifica il divisore che deve essere usato per il calcolo della varianza. I valori possibili sono: 253

DF - saranno usati i gradi di libert N-1 WEIGHT - sar usata la somma dei pesi N - sar usato il numero di osservazioni N WDF - sar usato la somma dei pesi meno 1. Ulteriori opzioni utilizzabili nella dichiarazione TABLE BOX= scrive una stringa o la legenda della pagina (se esiste una dimensione di pagina) nel rettangolo in alto a sinistra. Esempio:

"TABLE .../BOX='abc';" scrive la stringa 'abc' nel rettangolo in alto a sinistra. "TABLE ...,...,.../BOX=_PAGE_;" scrive il nome ed il valore della variabile della dimensione pagina nel rettangolo in alto a sinistra. FUZZ=nnn nnn un valore fornito dall'utente con il quale i valori delle variabili di analisi saranno comparati per eliminare quelli che risultano inferiori a nnn. Un numero che risulti, in valore assoluto, minore di nnn verr trattato come zero. In assenza di altre specifiche, il valore di FUZZ usato dalla procedura il pi piccolo numero floating point rappresentabile sul calcolatore in uso. MISSTEXT=' stringa ' stringa una descrizione scelta dall'utente, lunga al massimo 20 caratteri che apparir nelle celle della tabella contenenti valori mancanti. PRINTMISS specifica che le pagine della tabella debbono avere tutte la stessa forma, cio debbono contenere il medesimo numero di righe e di colonne di intestazione nello stesso ordine. RTSPACE=n RTS=n n un intero positivo che specifica il numero di caratteri disponibili per la stampa delle intestazioni di riga. In assenza di questa opzione la procedura usa un quarto del valore assunto dal parametro LINESIZE in quel momento. ROW=spacing spacing pu assumere i valori: FLOAT o CONSTANT; in presenza di intestazioni di riga bianche, nella 254

dimensione riga, derivanti ad esempio dall'associazione di etichette composte dal solo carattere spazio (SUM=' ', NOMERAP=' ', ecc.) la PROC TABULATE riserva spazio in tabella per dette descrizioni e questo si traduce nella presenza di una o pi colonne bianche; se si volessero sopprimere dette colonne bianche basta inserire l'opzione ROW=FLOAT. CONDENSE permette la stampa di pi tavole in una sola pagina fisica, se lo spazio lo permette (se ci stanno per intero). Detta opzione pu risultare utile quando, avendo usato nella dichiarazione TABLE la dimensione 'pagina', per ragioni di economia di stampa, si desiderasse accorpare al meglio le tavole prodotte. Per i dettagli circa le opzioni non trattate negli esempi mostrati in questo capitolo si rimanda il lettore alla lettura del manuale: SAS Guide to TABULATE Processing.

6.9.

La procedura PLOT

La procedura PLOT in grado di produrre diagrammi cartesiani, cio di rappresentare nel piano l'andamento di una variabile in funzione di un'altra. I dati devono essere contenuti in un archivio SAS e a ciascuna coppia di valori, ciascuno proveniente da una variabile, la procedura PLOT fa corrispondere un punto nel disegno. Mediante la PROC PLOT non possibile richiedere particolari accorgimenti grafici quali, ad esempio, la generazione di una spezzata che congiunga i punti del piano o la loro interpolazione mediante un'opportuna curva, l'uso del colore o di simboli grafici, ecc.. Queste e moltissime altre possibilit sono offerte dalla procedura GPLOT che fa parte della componente SAS/GRAPH che verr trattato nel capitolo 10. Le variabili del disegno possono essere anche di tipo non numerico ed inoltre possibile personalizzare le figure in uscita mediante una serie di opzioni di personalizzazione; gli esempi che seguono mostrano alcune delle principali opzioni possibili. La sintassi della procedura la seguente: PROC PLOT [opzioni]; BY variabile(i); PLOT <diagrammi_richiesti> / [opzioni]; La dichiarazione BY pu essere usata per ripartire logicamente le osservazioni dell'archivio in pi sottogruppi (in funzione dei valori diversi assunti dalle variabili in essa elencate); la procedura disegna un grafico per ciascun sottogruppo. Se la dichiarazione BY 255

presente, occorre che l'archivio di ingresso alla procedura sia ordinato in base alle variabili citate nella BY. La dichiarazione PLOT, oltre che stabilire il numero di grafici da produrre, indica alla procedura quali sono le coppie di variabili da associare a ciascun disegno. Detta dichiarazione pu apparire secondo le seguenti forme:
PLOT PLOT PLOT PLOT <variabile_verticale>*<variabile_orizzontale>; <variabile_verticale>*<variabile_orizzontale>='carattere'; <variabile_verticale>*<variabile_orizzontale>=variabile; (<variabile_verticale_1> <variabile_verticale_2>) * (<variabile_orizzontale_1> <variabile_orizzontale_2>);

Quest'ultima forma equivalente a: PLOT <variabile_verticale_1>*<variabile_orizzontale_1> <variabile_verticale_1>*<variabile_orizzontale_2> <variabile_verticale_2>*<variabile_orizzontale_1> <variabile_verticale_2>*<variabile_orizzontale_2>; rappresenta il nome della variabile, numerica o non, da assegnare all'asse verticale; rappresenta il nome della variabile, numerica o non, da assegnare all'asse orizzontale; rappresenta un carattere, a scelta dell'utente, che verr usato per indicare i punti nel grafico; rappresenta il nome di una variabile i cui valori saranno utilizzati per rappresentare i punti nel grafico; detta variabile pu essere numerica o non numerica; per rappresentare il punto relativo all'i-esima osservazione, la procedura sceglie il primo carattere a sinistra dell'i-esimo valore formattato di variabile . Nel caso in cui pi osservazioni generassero lo stesso punto nel grafico, il carattere di rappresentazione scelto dal valore formattato che variabile assume nella prima delle osservazioni in questione.

In particolare: variabile_verticale

variabile_orizzontale

carattere

variabile

A titolo d'esempio, si supponga di volere utilizzare la procedura PLOT per compiere delle analisi di vendita relative ad un dato periodo dell'anno. 256

Come si vede dal passo del programma mostrato in figura 6.48.1, l'archivio DATISAS.PERIODO contiene tante osservazioni quante sono le vendite effettuate nel periodo in questione; ciascuna osservazione fa riferimento ad una vendita e riporta, oltre al cognome del venditore e alla data, anche il numero di pezzi venduti.
DATA DATISAS.PERIODO; INPUT NOMERAP $ 1-10 @14 DATAVE DDMMYY8. NUMERO 26-27; FORMAT DATAVE DDMMYY8.; CARDS; ARTALE 04/1/88 10 ARTALE 05/1/88 5 ARTALE 06/1/88 4 ARTALE 07/1/88 1 ARTALE 08/1/88 15 ARTALE 11/1/88 20 ARTALE 12/1/88 10 ARTALE 13/1/88 5 ARTALE 14/1/88 20 BANTI 05/1/88 21 BANTI 06/1/88 4 BANTI 07/1/88 8 BANTI 08/1/88 9 BANTI 11/1/88 10 BANTI 12/1/88 7 BANTI 13/1/88 13 BANTI 14/1/88 11 BANTI 15/1/88 6 ;

Figura 6.48.1: Programma di generazione dei dati (parte N.1) Affinch si possano comparare globalmente i dati di vendita, usando la PLOT, opportuno riorganizzarli. Questa operazione effettuata nei passi successivi mostrati in figura 6.48.2 che prevedono rispettivamente: la generazione di due archivi contenenti ciascuno le osservazioni relative ad un singolo venditore; l'ordinamento dei due archivi per data di vendita; la fusione orizzontale (merge) per data di vendita dei due archivi, in modo da creare una osservazione per ciascuna data di vendita contenente tutte le operazioni effettuate in quel giorno. Per quanto concerne quest'ultima fase si noti che l'accorgimento di cambiare nome alle variabili provenienti dai due archivi ARTALE e BANTI necessario poich detti archivi contengono variabili aventi lo stesso nome. La figura 6.49 mostra il contenuto dell'archivio MERGE prodotto dal programma di figura 6.48.2.

257

DATA ARTALE BANTI; SET DATISAS.PERIODO; IF NOMERAP='ARTALE' THEN OUTPUT ARTALE; ELSE OUTPUT BANTI; PROC SORT DATA=ARTALE; BY DATAVE; PROC SORT DATA=BANTI; BY DATAVE; DATA MERGE; MERGE ARTALE(RENAME=(NOMERAP=NOMERAP1 NUMERO=NUMERO1)) BANTI(RENAME=(NOMERAP=NOMERAP2 NUMERO=NUMERO2)); BY DATAVE; PROC PRINT DATA=MERGE; ID DATAVE; RUN;

Figura 6.48.2: Programma di generazione dei dati (parte N.2)

DATAVE 04/01/88 05/01/88 06/01/88 07/01/88 08/01/88 11/01/88 12/01/88 13/01/88 14/01/88 15/01/88

NOMERAP1 ARTALE ARTALE ARTALE ARTALE ARTALE ARTALE ARTALE ARTALE ARTALE

NUMERO1 10 5 4 1 15 20 10 5 20 .

NOMERAP2 BANTI BANTI BANTI BANTI BANTI BANTI BANTI BANTI BANTI

NUMERO2 . 21 4 8 9 10 7 13 11 6

Figura 6.49: Archivio usato per negli esempi di PROC PLOT Per ottenere un semplice diagramma che mostri l'andamento delle vendite effettuate dal Sig. Artale in funzione della data di vendita, basta eseguire il programma di figura 6.50.
TITLE 'ANDAMENTO DELLE VENDITE DEL SIG. ARTALE'; PROC PLOT DATA=MERGE; PLOT NUMERO1*DATAVE; RUN;

Figura 6.50: Esempio di PROC PLOT In figura 6.51 viene mostrata l'uscita della PROC PLOT. Dall'osservazione di questa figura, si nota che la PLOT automaticamente inserisce una legenda (dopo l'ultima riga di titolo) mediante la quale viene segnalato che i punti del grafico possono essere evidenziati mediante i caratteri A, B, C, D, ......., a seconda che contribuiscano a formare quel punto, rispettivamente, 1, 2, 3, 4, .... osservazioni dell'archivio.

258

La procedura, con una nota in fondo al grafico, segnala anche il numero di valori mancanti presenti nell'archivio; ad esempio in figura 6.51, questo numero pari ad 1, ed relativo alla mancanza di vendite nel giorno 15/01/88. Infine si noti che, in assenza di opzioni di personalizzazione, le scale e le dimensioni del disegno sono state scelte automaticamente dalla procedura. E' possibile disegnare l'andamento delle vendite del Sig. Banti alla stessa maniera di quanto fatto per il Sig. Artale ma, data la similitudine del grafico risultante, questo non viene fatto.
ANDAMENTO DELLE VENDITE DEL SIG. ARTALE PLOT OF NUMERO1*DATAVE LEGEND: A = 1 OBS, B = 2 OBS, ETC. NUMERO1 | | | | 20 + A A 19 + 18 + 17 + 16 + 15 + A 14 + 13 + 12 + 11 + 10 + A A 9 + 8 + 7 + 6 + 5 + A A 4 + A 3 + 2 + 1 + A | | | | ----+---------+---------+---------+---------+---------+--------04/01/88 06/01/88 08/01/88 10/01/88 12/01/88 14/01/88 DATAVE NOTE: 1 OBS HAD MISSING VALUES

Figura 6.51: Uscita prodotta dal programma di figura 6.50 Pu risultare interessante apportare alcune personalizzazioni al disegno. Supponiamo di voler compiere una analisi comparativa degli andamenti delle vendite effettuate dai due venditori. Il programma mostrato in figura 6.52 permette di ottenere la sovrapposizione dei grafici di vendita relativi ai due venditori. Come si pu osservare dalla dichiarazione PLOT, per distinguere i punti relativi al Sig. Artale da quelli del Sig. Banti, sono stati usati 259

rispettivamente i caratteri "+" e "*". Inoltre si nota la presenza della opzione OVERLAY che comanda la sovrapposizione dei grafici (cosa possibile perch essi hanno in comune la variabile orizzontale). L'aspetto del disegno stato curato ulteriormente assegnando delle etichette al nome delle variabili.
TITLE 'ANDAMENTO COMPARATO DELLE VENDITE'; TITLE2 'SIG. ARTALE = + SIG. BANTI = *'; PROC PLOT DATA=MERGE NOLEGEND; PLOT NUMERO1*DATAVE='+' NUMERO2*DATAVE='*' /OVERLAY; LABEL NUMERO1='QUANTITA'' VENDUTA' DATAVE ='DATA DI VENDITA: GG/MM/AA'; RUN;

Figura 6.52: Esempio di PROC PLOT personalizzato In figura 6.53 viene mostrata l'uscita generata dalla PROC PLOT.
ANDAMENTO COMPARATO DELLE VENDITE SIG. ARTALE = + SIG. BANTI = *

Q U A N T I T A ' V E N D U T A

21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1

| | | | + * + + + + + + + + + + + * + + * + + * + + * + * + * + * + + + + + + + + + | | | | ------+---------+---------+---------+---------+---------+---------04/01/88 06/01/88 08/01/88 10/01/88 12/01/88 14/01/88 DATA DI VENDITA: GG/MM/AA

NOTE:

2 OBS HAD MISSING VALUES

Figura 6.53: Uscita prodotta dal programma di figura 6.52 Si desidera ora apportare ulteriori personalizzazioni al grafico, ordinando alla procedura di usare una nostra scala per l'asse orizzontale in modo che su di esso compaiano tutti i giorni nei quali 260

stata effettuata almeno una vendita. Nel programma di figura 6.54, mediante le opzioni HAXIS stato richiesto di scalare l'asse orizzontale a partire dal 1/1/88 al 15/1/88 ad intervalli di 1 giorno. A tal proposito si ricordi quanto detto nel capitolo 4 a riguardo delle costanti di tipo data, tempo e data-tempo; la sintassi deve essere necessariamente del tipo: HAXIS= da TO a BY <ad_intervalli_di> dove: da ed a devono seguire le stesse regole valide per le costanti di tipo data, tempo e data-tempo; deve essere: un numero, oppure una parola scelta tra: DAY, WEEK, MONTH, YEAR, HOUR, MINUTE, SECOND, DTDAY, DTWEEK, ecc.. Mediante l'opzione VREF= possibile inserire uno o pi linee di riferimento sull'asse verticale in corrispondenza dei valori che seguono il segno "=". E' anche possibile stabilire, mediante l'opzione VREFCHAR=, il carattere da usarsi per tracciare dette linee.
TITLE 'ANDAMENTO COMPARATO DELLE VENDITE DI GENNAIO'; TITLE2 'ESEMPIO D''USO DELLE OPZIONI: HAXIS, VREF E VREFCHAR'; TITLE3 'SIG. ARTALE = + SIG. BANTI = *'; PROC PLOT NOLEGEND; PLOT NUMERO1*DATAVE='+' NUMERO2*DATAVE='*' /OVERLAY HAXIS='01JAN88'D TO '15JAN88'D BY 1 VREF=10 VREFCHAR='='; FORMAT DATAVE DDMMYY2.; LABEL NUMERO1='QUANTITA'' VENDUTA' DATAVE='DATA DI VENDITA'; RUN;

ad_intervalli_di

Figura 6.54: Esempio di PROC PLOT personalizzato In figura 6.55 viene mostrata l'uscita generata dalla PROC PLOT. Si noti che sull'asse delle ascisse compaiono i giorni (01, 02, ..., 15) in quanto nel formato scelto per rappresentare la variabile DATAVE, cio "DDMMYY2.", sono state specificate solamente 2 posizioni. 261

Esistono anche altre opzioni per modificare la forma del disegno (VPOS, HPOS, VSPACE ed HSPACE). Nel programma di figura 6.56 stata usata l'opzione VSPACE=, mediante la quale si definisce il numero di righe che devono intercorrere tra un trattino posto sull'asse verticale ed un altro. Agendo su questo valore, ed usando anche l'opzione VPOS, che specifica il numero massimo di linee a disposizione per il disegno, possibile di fatto "allungare" le figure prodotte dalla procedura.
ANDAMENTO COMPARATO DELLE VENDITE DI GENNAIO ESEMPIO D'USO DELLE OPZIONI: HAXIS, VREF E VREFCHAR SIG. ARTALE = + SIG. BANTI = * | | | | + * + + + + + + + + + + + * + + * +================+===========================*===+================= + * + * + * + * + + + + + + + + + | | | -----+---+---+---+---+---+---+---+---+---+---+---+---+---+---+----01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 DATA DI VENDITA NOTE: 2 OBS HAD MISSING VALUES OR WERE OUT OF RANGE

Q U A N T I T A ' V E N D U T A

21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1

Figura 6.55: Uscita prodotta dal programma di figura 6.54 L'ultima osservazione relativa alla presenza dell'opzione VZERO, la quale comanda che la prima tacca in basso dell'asse verticale deve essere posta in corrispondenza del valore 0. Questa opzione verr ignorata nei casi in cui la variabile verticale assume valori negativi, oppure se presente una opzione VAXIS= (per assegnare una scala all'asse verticale) che non parte dal valore 0.
TITLE TITLE2 TITLE3 TITLE4 'ANDAMENTO COMPARATO DELLE VENDITE'; 'ESEMPIO D''USO DELLE OPZIONI: OVERLAY, HAXIS,'; 'VAXIS, VREF, VREFCHAR, E VSPACE'; 'SIG. ARTALE = + SIG. BANTI = *';

262

PROC PLOT NOLEGEND; PLOT NUMERO1*DATAVE='+' NUMERO2*DATAVE='*' /OVERLAY HAXIS='01JAN88'D TO '15JAN88'D BY 1 VAXIS=0 TO 21 BY 1 VZERO VREF=10 VREFCHAR='=' VSPACE=2; LABEL NUMERO1='QUANTITA'' VENDUTA' DATAVE='DATA DI VENDITA'; FORMAT DATAVE DATE5.; RUN;

Figura 6.56: Esempio di PROC PLOT personalizzato

6.10. Introduzione alla rapporti personalizzati

produzione

di

Nonostante che le numerose procedure SAS esaminate fino ad ora siano in grado di soddisfare una estesa gamma di esigenze, talvolta capita di dover produrre dei rapporti in formati che non sono ottenibili con nessuna procedura standard. In questo paragrafo vedremo come possibile produrre rapporti personalizzati, facendo uso delle possibilit di programmazione offerte dal passo di DATA. In particolare esamineremo le due dichiarazioni, FILE e PUT, specializzate per questo scopo. Come considerazione generale va tenuto presente che questa soluzione in grado di risolvere qualsiasi tipo di esigenza anche se richiede un minimo di esperienza di programmazione. Per gli utenti alle prime armi certamente consigliabile l'utilizzo, ove possibile, delle procedure SAS disponibili, al limite sacrificando qualcosa in termini di estetica, ma guadagnando certamente in termini di tempo impiegato ad ottenere determinati risultati.

6.10.1.

La dichiarazione PUT e FILE

Queste dichiarazioni vengono utilizzate nel sistema SAS per scrivere, su un qualunque supporto esterno, archivi non SAS. Esse hanno caratteristiche e sintassi simili a quelle delle dichiarazioni INFILE ed INPUT, gi viste nel capitolo 5 e che permettono, rispettivamente, di puntare e leggere dati da un archivio esterno non SAS. La dichiarazione FILE punta all'archivio in uscita, e la dichiarazione PUT comanda la scrittura di uno o pi record in uscita; inoltre, la PUT specifica il formato di scrittura dei dati.

263

Figura 6.57: Uscita prodotta dal programma di figura 6.56


COMPARAZIONE TRA LE VENDITE EFFETTUATE DAI SIGG. ARTALE E BANTI ESEMPIO D'USO DELLE OPZIONI: OVERLAY, HAXIS, VAXIS, VREF, VREFCHAR, E VSPACE SIG. ARTALE = + SIG. BANTI = * 21 + * | 20 + + + | 19 + | 18 + | 17 + | 16 + | 15 + + | 14 + | 13 + * | 12 + | 11 + * | 10 +================+===========================*===+================= | 9 + * | 8 + * | 7 + * | 6 + * | 5 + + + | 4 + + | 3 + | 2 + | 1 + + | 0 + -----+---+---+---+---+---+---+---+---+---+---+---+---+---+---+----0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 J J J J J J J J J J J J J J J A A A A A A A A A A A A A A A N N N N N N N N N N N N N N N DATA DI VENDITA NOTE: 2 OBS HAD MISSING VALUES OR WERE OUT OF RANGE

Q U A N T I T A ' V E N D U T A

264

La sintassi generale delle due dichiarazioni la seguente: FILE <puntatore_file> [opzioni]; PUT [<specifiche_di_scrittura>] ......... ; Analogamente a quanto visto nel contesto della INFILE, puntatore_file un nome logico scelto dall'utente che nella FILE indica dove l'archivio deve essere scritto; puntatore_file pu essere lungo al massimo 8 caratteri e deve essere stato precedentemente associato, con un comando di sistema, al nome completo dell'archivio da scrivere. Nella dichiarazione PUT, specifiche_di_scrittura stanno ad indicare in quale posizione e con quale formato i dati devono essere scritti nel record di uscita. Generalmente, specifiche_di_scrittura potr assumere le seguenti forme: variabile 'testo' che rappresenta il nome della variabile da scrivere sul record; che specifica una stringa di caratteri racchiusi tra apici da scrivere sul record;

controllo_del_puntatore che specifica la posizione (orizzontale e/o verticale) di inizio di scrittura di un campo nel record; _ALL_ che ordina la scrittura sul record di uscita di tutte le variabili contenute del Program Data Vector (comprese le variabili automatiche _N_ ed ERROR) nel formato variabile=valore.

Molto spesso la dichiarazione PUT prevede al suo interno dei formati associati a delle variabili. Vi sono 4 modi per controllare dove i testi o le variabili devono essere stampati all'interno della pagina: @n sposta il cursore orizzontale (cursore di colonna) alla posizione n-esima della riga corrente; +n sposta il cursore, in avanti o in dietro sulla riga corrente, di n posizioni; n pu essere anche una variabile numerica che assume un valore negativo; salta a riga nuova; sposta il cursore verticale (cursore di riga) a colonna 1 della n-esima riga della pagina corrente.

/ #n

Per quanto riguarda la sintassi della dichiarazione FILE, nel caso della produzione di rapporti, sufficiente far assumere a 265

puntatore_file il valore speciale PRINT: FILE PRINT [opzioni]; Le principali opzioni sono le seguenti: NOTITLES equivale ad una dichiarazione " TITLE ; " in un programma SAS; sopprime la validit di eventuali dichiarazioni TITLE codificate in precedenza. E' consigliabile specificare sempre questa opzione, in particolare quando si intende intestare le pagine mediante un routine personalizzata presente nel passo di DATA. HEADER=etichetta specifica una etichetta a cui il passo di DATA deve saltare tutte le volte che comincia una nuova pagina di stampa. Vengono automaticamente eseguite tutte le dichiarazioni fino a che viene incontrata una "RETURN", la quale trasferisce il controllo alla dichiarazione che segue la FILE. Esempio:
DATA _NULL_; FILE PRINT NOTITLES HEADER=TESTATA; INFILE .......... ; INPUT .......... ; ....... altre dichiarazioni ...... PUT .......... ; RETURN; TESTATA: PUT .......... ; RETURN; RUN;

Questo esempio mostra la struttura di un tipico di passo di DATA per la produzione di rapporti, nel quale sono previste righe di dettaglio e di testata (o di intestazione di pagina). LL=variabile definisce una variabile SAS il cui valore rappresenta il numero di linee ancora disponibili sulla pagina corrente. N=PS questa opzione permette all'utente di poter puntare qualsiasi posizione di stampa della pagina prima che essa venga rilasciata per la scrittura; si abbia ad esempio un archivio contenente un elenco di nomi ordinato alfabeticamente e si voglia ottenere una stampa dell'archivio disponendo i nomi in ordine alfabetico su tre colonne per pagina. Un possibile passo di DATA viene mostrato di seguito. Esso stampa nelle righe 1-60 ("DO LINEA=1 TO 60") i 266

primi 60 nomi a partire da colonna 1 ("DO COLONNA=1"), i secondi 60 a partire dalla riga 1 di colonna 40 ("DO COLONNA=40") e gli ultimi 60 a partire dalla riga 1 di colonna 80 ("DO COLONNA=80"); a questo punto i due cicli di DO terminano e viene stampata la prima pagina del prospetto per mezzo della dichiarazione PUT _PAGE_ , che rappresenta una forma particolare della istruzione PUT. Nel caso che i nomi fossero meno di 180, e che quindi la pagina risultasse incompleta, essa verrebbe rilasciata e stampata dopo avere letto l'ultimo record dal file ELENCO.NOMI.
DATA _NULL_; FILE PRINT NOTITLES N=PS; DO COLONNA =1, 40, 80 ; DO LINEA = 1 TO 60 ; SET ELENCO.NOMI ; PUT #LINEA @COLONNA NOME $30. ; END; END; PUT _PAGE_; RUN;

6.10.2.

Alcuni esempi

Come primo esempio, vogliamo effettuare una stampa dell'archivio SAS DATISAS.VENDITE, gi usato in questo capitolo, in forma simile a quella della PROC PRINT. Supponiamo di stampare le variabili NOMERAP, DATAVE, ARTICOLO, NUMERO, COSTO ed il numero di ciascuna osservazione, che si trova sotto la colonna OBS. Il passo di DATA, mostrato in figura 6.58 d come risultato il prospetto mostrato in figura 6.59.
DATA _NULL_ ; SET DATISAS.VENDITE; FILE PRINT HEADER=TESTATA NOTITLES; PUT @2 _N_ 2. +1 NOMERAP $8. @13 DATAVE DDMMYY8. +1 ARTICOLO $20. +1 NUMERO 2. +3 COSTO 6. ; RETURN; TESTATA: PUT @1 'OBS NOMERAP DATAVE ARTICOLO' @41 'NUMERO COSTO'/; RETURN;

Figura 6.58 : Programma per ottenere una uscita simile alla PROC PRINT Il programma molto semplice, e usa l'opzione HEADER per l'intestazio- ne. La stampa del numero di osservazione su ogni riga, realizzata utiliz- zando la variabile automatica _N_. Il prossimo esempio, il cui programma mostrato in figura 6.60, risulta un p pi complesso ed il rapporto prodotto mostrato in figura 6.61. 267

Rispetto al prospetto di figura 6.59, viene calcolato il totale dei pezzi venduti e l'importo fatturato da ogni venditore, nonch il totale generale. Inoltre non viene ripetuto il nome del venditore nelle righe successive alla prima. Per ottenere questo risultato l'archivio DATISAS.VENDITE viene letto utilizzando l'opzione END= e la dichiarazione BY per poter far uso delle variabili automatiche FIRST.NOMERAP e LAST.NOMERAP. Quando viene letta la prima osservazione relativa ad un nuovo venditore, ("FIRST.NOMERAP=1")il suo nome viene scritto nella prima riga dati.
OBS NOMERAP 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Artale Artale Artale Artale Artale Artale Artale Artale Artale Banti Banti Banti Banti Banti Banti Banti Banti Banti DATAVE 03/01/87 05/01/87 05/01/87 13/02/87 14/02/87 17/02/87 03/03/87 04/03/87 10/03/87 03/01/87 03/01/87 05/02/87 13/02/87 16/02/87 16/02/87 10/03/87 16/03/87 21/03/87 ARTICOLO NUMERO 10 1 2 1 1 1 20 10 20 1 1 3 30 1 1 2 20 10 COSTO 5000 150000 400000 200000 180000 150000 4000 5700 5000 275000 400000 600000 5000 180000 150000 150000 5700 4000

Cartucce Scheda I/O Interfaccia GPX Video a colori Package "Multiplan" Video bianco-nero Pacco carta A4 Pennarelli plotter Cartucce Interfaccia KSP Package "Astra" Video a colori Pacco di carta A3 Package "Multiplan" Scheda I/O Scheda I/O Pennarelli plotter Pacco carta A4

Figura 6.59: Tabulato prodotto dal programma di figura 6.58

DATA _NULL_ ; SET DATISAS.VENDITE END=EOF; BY NOMERAP; FILE PRINT HEADER=TESTATA NOTITLES ; IMPORTO=NUMERO*COSTO; IF FIRST.NOMERAP THEN PUT @2 NOMERAP $8. @; PUT @11 DATAVE DDMMYY8. +1 ARTICOLO $20. @43 NUMERO 2. @47 IMPORTO 7.; TOTPEZZI+NUMERO; TOTIMP+IMPORTO; IF LAST.NOMERAP THEN DO; PUT @42 '___' @47 '_______'/ @1 '*TOTALE ' NOMERAP @17 '*' @42 TOTPEZZI 3. @47 TOTIMP 7. /; TOTALE1 + TOTPEZZI; TOTALE2 + TOTIMP ; TOTPEZZI=0; TOTIMP=0; END; IF EOF=1 THEN PUT @42 '===' @47 '======='/ @1 '*TOTALE GENERALE*' @42 TOTALE1 3. @47 TOTALE2 7.; RETURN; TESTATA: PUT @1 ' NOME DATA ARTICOLO' @40 'PEZZI IMPORTO'; PUT @1 'VENDITORE VENDITA' @39 'VENDUTI VENDITA'/; RETURN;

Figura 6.60: Programma che calcola i totali per ogni venditore 268

La riga di totalizzazione relativa al singolo venditore viene scritta quando letta l'ultima osservazione di quel venditore (cio "LAST.NOMERAP=1"); in quel caso sono stampati i contenuti delle variabili TOTPEZZI e TOTIMP, che poi vengono azzerate per consentire la totalizzazione relativa al nuovo venditore. Vengono anche aggiornati i totali generali (variabili TOTALE1 e TOTALE2). Quando infine viene letta l'ultima osservazione dei dati (cio "EOF=1"), viene scritta la riga dei totali generali. Anche in questo caso la intestazione viene effettuata per mezzo della opzione HEADER.
NOME DATA VENDITORE VENDITA Artale 03/01/87 05/01/87 05/01/87 13/02/87 14/02/87 17/02/87 03/03/87 04/03/87 10/03/87 * Interfaccia KSP Package "Astra" Video a colori Pacco di carta A3 Package "Multiplan" Scheda I/O Scheda I/O Pennarelli plotter Pacco carta A4 ARTICOLO PEZZI IMPORTO VENDUTI VENDITA 10 1 2 1 1 1 20 10 20 ___ 66 1 1 3 30 1 1 2 20 10 ___ 69 === 135 50000 150000 800000 200000 180000 150000 80000 57000 100000 _______ 1767000 275000 400000 1800000 150000 180000 150000 300000 114000 40000 _______ 3409000 ======= 5176000

Cartucce Scheda I/O Interfaccia GPX Video a colori Package "Multiplan" Video bianco-nero Pacco carta A4 Pennarelli plotter Cartucce

*TOTALE Artale Banti

03/01/87 03/01/87 05/02/87 13/02/87 16/02/87 16/02/87 10/03/87 16/03/87 21/03/87 *

*TOTALE Banti

*TOTALE GENERALE*

Figura 6.61: Tabulato prodotto dal programma di figura 6.60 L'ultimo esempio che viene mostrato fa uso della opzione N=PS, ovvero la stampa non avviene pi riga dopo riga, ma viene prima preparata la pagina da stampare in memoria, per poi effettuare la stampa vera e propria per mezzo della dichiarazione PUT _PAGE_. Si vuole ottenere un tabulato, relativo alle vendite di Febbraio, che riporti sul lato sinistro una colonna con tutti i giorni del mese, seguita da tante colonne quanti sono i venditori, in ciascuna delle quali deve comparire il fatturato conseguito da ogni venditore nei vari giorni, ed al termine il fatturato globale conseguito nel mese. Il programma di figura 6.62 realizza quanto richiesto; esso si compone 269

di due passi di DATA. Tale osservazione scritta quando "LAST.DATAVE=1". Il primo passo estrae dal file DATISAS.VENDITE le sole osservazioni relative al mese di Febbraio creando un'unica osservazione per giorno di vendita contenente il totale fatturato (variabile IMPORTO), nel caso che un venditore abbia effettuato pi vendite in una giornata. Tale osservazione scritta quando "LAST.DATAVE=1". Il secondo passo di DATA scrive, durante il primo ciclo di esecuzione nel quale _N_ risulta uguale ad 1, una intestazione e la colonna contenente tutti i giorni di Febbraio, utilizzando la nota propriet delle date di essere rappresentate in giorni. Il "DO WHILE" prosegue fino a che "MONTH(DATA)=2" ovvero per 29 cicli (si deve tener conto che l'anno 1988 bisestile!).
DATA FEBBRAIO; SET DATISAS.VENDITE; BY NOMERAP DATAVE; IF MONTH(DATAVE)=2; /* ESTRAE DATI DI FEBBRAIO */ IF FIRST.DATAVE THEN IMPORTO=0; IMPORTO+(NUMERO*COSTO); IF LAST.DATAVE; DATA _NULL_ ; RETAIN ULTIMA 0 DATA '01FEB88'D RIGA 5 COLONNA 10; FILE PRINT NOTITLES N=PS; IF _N_ = 1 THEN DO; PUT #1 @6 'FATTURATO DEI VENDITORI RELATIVO AL MESE DI FEBBRAIO' // @1 'DATA'; DO WHILE (MONTH(DATA)=2); PUT #RIGA @1 DATA DATE5.; DATA=DATA+1; RIGA+1; END; ULTIMA=RIGA+1; END; SET FEBBRAIO END=EOF; BY NOMERAP; RIGA=DAY(DATAVE)+4; /*TIENE CONTO DELLA INTESTAZIONE*/ PUT #RIGA @COLONNA IMPORTO 7.; TOTALE+IMPORTO; IF LAST.NOMERAP THEN DO; PUT #3 @COLONNA NOMERAP $8. ; PUT #ULTIMA @1 '*TOTALI*' @COLONNA TOTALE 7.; COLONNA+10; TOTALE=0; END; IF EOF=1 THEN PUT _PAGE_;

Figura 6.62: Programma che utilizza l'opzione N=PS Non viene usata in questo esempio l'opzione HEADER, perch il tabulato risultante sarebbe contenuto comunque in una pagina, anche 270

se fossero presenti altri venditori. Viene infine calcolata la variabile ULTIMA, contenente il numero di riga a cui debbono essere scritti i totali. Successivamente vengono lette le varie osservazioni, e viene scritto il fatturato di ogni venditore alla riga e colonna opportuna (#RIGA coincide con il giorno da 1 a 29 aumentato delle righe della intestazione, @COLONNA vale 10 per il primo venditore, 20 per il secondo ecc.). Ogni importo totalizzato nella variabile TOTALE, che viene scritta dopo aver letto l'ultima osservazione relativa ad ogni venditore. Anche in questo caso si fa uso della variabile LAST.NOMERAP. Dopo aver letto l'ultima osservazione relativa all'ultimo venditore (cio "EOF=1"), viene finalmente stampata la pagina completa.
FATTURATO DEI VENDITORI RELATIVO AL MESE DI FEBBRAIO DATA 01FEB 02FEB 03FEB 04FEB 05FEB 06FEB 07FEB 08FEB 09FEB 10FEB 11FEB 12FEB 13FEB 14FEB 15FEB 16FEB 17FEB 18FEB 19FEB 20FEB 21FEB 22FEB 23FEB 24FEB 25FEB 26FEB 27FEB 28FEB 29FEB *TOTALI* Artale Banti

1800000

200000 180000

150000

330000 150000

530000

2280000

Figura 6.63: Tabulato prodotto dal programma di figura 6.62

271

7. Analisi dei dati cenni di procedure statistiche

7.1.

Considerazioni generali

Spesso si hanno molti dati da elaborare e questo implica l'impossibilit di analizzarli mediante la semplice lettura dei lunghi tabulati sui quali sono rappresentati. In questi casi, quindi, non possibile derivare considerazioni circa la loro forma, qualit, eventuale presenza di valori mancanti, e soprattutto sul "cosa" essi nell'insieme possono dirci a riguardo del fenomeno in studio. E' allora opportuno ricorrere al calcolo di statistiche descrittive quali: percentuali, medie, scarti quadratici medi, coefficienti di correlazione, ecc., operate sull'insieme dei dati o su campioni significativi di essi. Con queste semplici elaborazioni possibile comprendere le caratteristiche principali dei dati, prima di proseguire eventualmente nell'indagine mediante l'applicazione di procedimenti matematico-statistici pi complessi. Il sistema SAS mette a disposizione una vastissima libreria di procedure matematico-statistiche; alcune di esse producono uscite facili da interpretare (basta conoscere rudimenti di statistica), mentre altre richiedono specifiche conoscenze della materia, ed una attenta consultazione dei manuali di riferimento in modo da interpretare correttamente i risultati ottenuti. In generale, si fa riferimento alle procedure mediante nomi mnemonici; anche le opzioni e le parolechiave usate per definire particolari richieste o statistiche sono standardizzate e di tipo mnemonico. Molte delle statistiche ottenibili possono essere fornite da pi di una procedura SAS ma, in base all'esperienza, si pu affermare che la maggior parte degli utilizzatori tendono ad usare la procedura di pi facile utilizzo, ignorando spesso che esistono delle precise valutazioni circa le prestazioni di ciascuna di esse quali: la memoria richiesta, il tipo di algoritmo implementato, i limiti al numero di dati in ingresso, ecc.. A coloro i quali intendessero approfondire questa tematica, si suggerisce la lettura dei manuali SAS User's Guide: Basics e SAS User's Guide:Statistics; in particolare si consiglia di consultare il paragrafo "Details" relativo alla procedura prescelta. 272

Infine si avverte il lettore che durante la lettura di questo capitolo incontrer alcune dichiarazioni gi spiegate nei capitoli precedenti; laddove ne venissero introdotte delle nuove, queste verranno prontamente descritte. In linea con lo spirito del libro, in questo capitolo verranno illustrate solo le procedure (sottolineate) di uso pi semplice e frequente tra quelle elencate di seguito: MEANS FREQ CORR REG SUMMARY UNIVARIATE TABULATE CHART

Dette procedure potranno facilmente aiutare gli utilizzatori durante le fasi di analisi di primo livello, mentre per l'apprendimento delle rimanenti procedure si rimanda il lettore ad altri capitoli del libro (per TABULATE e CHART) od ai manuali SAS (per SUMMARY e UNIVARIATE). Inoltre, in questo capitolo, stato inserito un semplice esempio della procedura REG, usata per stimare i parametri caratteristici di una retta di regressione.

7.2.

Uso della procedura MEANS

La procedura MEANS serve per produrre statistiche relative a tutte le osservazioni di un archivio SAS o ad un loro sottoinsieme, ad esempio, relativo ai soggetti aventi un determinato gruppo sanguigno o appartenenti ad un dato dipartimento aziendale. La PROC MEANS risulta di pi facile uso rispetto ad altre procedure SAS quali: UNIVARIATE, SUMMARY, CHART e TABULATE. La forma generale per richiamare la procedura : PROC MEANS [opzioni]; [VAR variabile(i);] La parola opzioni potr essere sostituita con una lista di opzioni o di parole-chiave valide. Di seguito viene riportata una lista parziale delle statistiche che la procedura MEANS pu fornire (il nome tra parentesi rappresenta la parola-chiave da indicare al posto di opzione): numero di valori mancanti (NMISS) numero di valori validi (N) 273

media aritmetica (MEAN) sommatoria (SUM) minimo (MIN) massimo (MAX) massimo-minimo (RANGE) varianza (VAR) deviazione standard (STD) errore standard (STDERR) somma dei quadrati corretta (CSS) somma dei quadrati non corretta (USS) coefficiente di variazione (CV) t di Student (T) probabilit di ottenere un valore assoluto maggiore del t di Student (PRT).

In generale, tutte le procedure statistiche compresa la MEANS, escludono dall'analisi i valori mancati. Se si omette la dichiarazione VAR, la procedura prende in considerazione tutte le variabili numeriche dell'archivio in oggetto. Come caso concreto, si consideri l'archivio SAS DATISAS.VENDITE avente la struttura mostrata in figura 7.1.
OBS NOMERAP 1 Artale 2 Artale 3 Artale 4 Artale 5 Artale 6 Artale 7 Artale 8 Artale 9 Artale 10 Banti 11 Banti 12 Banti 13 Banti 14 Banti 15 Banti 16 Banti 17 Banti 18 Banti DATAVE ARTICOLO NUMERO 03/01/87 Cartucce 10 05/01/87 Scheda I/O 1 05/01/87 Interfaccia GPX 2 13/02/87 Video a colori 1 14/02/87 Package "Multiplan" 1 17/02/87 Video bianco-nero 1 03/03/87 Pacco carta A4 20 04/03/87 Pennarelli plotter 10 10/03/87 Cartucce 20 03/01/87 Interfaccia KSP 1 03/01/87 Package "Astra" 1 05/02/87 Video a colori 3 13/02/87 Pacco di carta A3 30 16/02/87 Package "Multiplan" 1 16/02/87 Scheda I/O 1 10/03/87 Scheda I/O 2 16/03/87 Pennarelli plotter 20 21/03/87 Pacco carta A4 10 COSTO TOTALE MESE GIORNO 5000 50000 1 7 150000 150000 1 2 400000 800000 1 2 200000 200000 2 6 180000 180000 2 7 150000 150000 2 3 4000 80000 3 3 5700 57000 3 4 5000 100000 3 3 275000 275000 1 7 400000 400000 1 7 600000 1800000 2 5 5000 150000 2 6 180000 180000 2 2 150000 150000 2 2 150000 300000 3 3 5700 114000 3 2 4000 40000 3 7

Figura 7.1: Archivio SAS DATISAS.VENDITE usato per gli esempi Siamo interessati inizialmente a conoscere, per ciascun venditore: il numero di operazioni di vendita effettuate; l'ammontare complessivo delle vendite; 274

il valor medio delle vendite effettuate; gli importi di vendita: minimo e massimo. Otterremo queste statistiche descrittive facendo eseguire il passo mostrato in figura 7.2, che usa la procedura MEANS.
TITLE 'DATI DI VENDITA PER RAPPRESENTANTE'; PROC MEANS DATA=DATISAS.VENDITE N SUM MEAN MIN MAX MAXDEC=2; BY NOMERAP; VAR TOTALE; RUN;

Figura 7.2: Esempio di uso della PROC MEANS


DATI DI VENDITA PER RAPPRESENTANTE VARIABLE N SUM MEAN MINIMUM VALUE MAXIMUM VALUE

---------------------------- NOMERAP=Artale ------------------------TOTALE 9 1767000.00 196333.33 50000.00 800000.00

---------------------------- NOMERAP=Banti -------------------------TOTALE 9 3409000.00 378777.78 40000.00 1800000.00

Figura 7.3: Output prodotto dal programma di figura 7.2 La dichiarazione PROC MEANS contiene una serie di opzioni quali: N, SUM, MEAN, MIN, MAX e MAXDEC=2. Le prime cinque opzioni indicano il tipo di statistiche descrittive che si intende ottenere, scelte tra quelle possibili ammesse dalla procedura in questione. Le opzioni SUM, MEAN, MIN e MAX richiedono il calcolo, rispettivamente, della sommatoria, della media aritmetica, del valore minimo e massimo delle variabili elencate nella dichiarazione VAR. L'opzione N richiede la stampa del numero di valori validi (non mancanti) assunti dalle variabili della dichiarazione VAR usati per il calcolo delle statistiche elencate sopra; infine, l'opzione MAXDEC=2 indica che il numero di cifre decimali desiderate 2; questa opzione far s che tutte le statistiche prodotte dalla procedura saranno arrotondate alla seconda cifra decimale. La dichiarazione VAR informa la procedura che si desidera ottenere statistiche solo per le variabili specificate, in questo caso, TOTALE; se avessimo omesso la dichiarazione VAR, la procedura avrebbe calcolato le statistiche desiderate per tutte le variabili numeriche dell'archivio. Supponiamo ora che alcuni valori della variabile TOTALE risultino mancanti, come mostrato nella figura 7.4, in particolare per quanto concerne la seconda e la settima osservazione. La 275

dichiarazione PROC MEANS del programma di figura 7.5 elenca, tra le opzioni scelte, anche NMISS che richiede il numero di valori mancanti assunti dalla variabile TOTALE; il risultato dell'elaborazione di questo passo mostrato in figura 7.6.
OBS NOMERAP 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Artale Artale Artale Artale Artale Artale Artale Artale Artale Banti Banti Banti Banti Banti Banti Banti Banti Banti DATAVE 03/01/87 05/01/87 05/01/87 13/02/87 14/02/87 17/02/87 03/03/87 04/03/87 10/03/87 03/01/87 03/01/87 05/02/87 13/02/87 16/02/87 16/02/87 10/03/87 16/03/87 21/03/87 ARTICOLO NUMERO 10 . 2 1 1 1 . 10 20 1 1 3 30 1 1 2 20 10 COSTO TOTALE MESE GIORNO 1 1 1 2 2 2 3 3 3 1 1 2 2 2 2 3 3 3 7 2 2 6 7 3 3 4 3 7 7 5 6 2 2 3 2 7

Cartucce Scheda I/O Interfaccia GPX Video a colori Package "Multiplan" Video bianco-nero Pacco carta A4 Pennarelli plotter Cartucce Interfaccia KSP Package "Astra" Video a colori Pacco di carta A3 Package "Multiplan" Scheda I/O Scheda I/O Pennarelli plotter Pacco carta A4

5000 50000 150000 . 400000 800000 200000 200000 180000 180000 150000 150000 4000 . 5700 57000 5000 100000 275000 275000 400000 400000 600000 1800000 5000 150000 180000 180000 150000 150000 150000 300000 5700 114000 4000 40000

Figura 7.4: Archivio SAS con qualche valore mancante

TITLE 'DATI DI VENDITA CON QUALCHE VALORE MANCANTE'; PROC MEANS DATA=DATISAS.VENDITE N NMISS SUM MEAN MAXDEC=2; VAR TOTALE; RUN;

Figura 7.5: Uso della PROC MEANS per segnalare il numero di valori mancanti di una variabile dell'archivio SAS Spesso necessario non solo stampare le statistiche ottenute elaborando un archivio SAS, ma anche conservarle su un altro archivio SAS, definito: "estratto".

DATI DI VENDITA CON QUALCHE VALORE MANCANTE VARIABLE TOTALE N 16 N MISSING 2 SUM 4946000.00 MEAN 309125.00

Figura 7.6: Output prodotto dal programma di figura 7.5

Questa tecnica permette di trattenere, sui dischi di lavoro, archivi di dimensioni decisamente inferiori rispetto a quelle degli archivi di 276

dettaglio originali; al termine di questa operazione, gli archivi originali possono migrare su dispositivi di memoria di massa pi capaci e meno costosi, ad esempio nastri. Il programma di figura 7.7 crea, a partire dall'archivio SAS di dettaglio DATISAS.VENDITE di figura 7.1, l'archivio estratto DATISAS.ESTRATTO mostrato in figura 7.8; quest'ultimo ha tante osservazioni quanti sono i valori diversi assunti dalla variabile oggetto di BY (NOMERAP); le osservazioni contengono oltre a NOMERAP, altre 3 variabili, cio: NVALORI, TOTVEND, MEDIAVEN.

OPTIONS PS=40 LS=72; PROC MEANS DATA=DATISAS.VENDITE NOPRINT; VAR TOTALE; BY NOMERAP; OUTPUT OUT=DATISAS.ESTRATTO N=NVALORI SUM=TOTVEND MEAN=MEDIAVEN; TITLE 'CREAZIONE DI UN ARCHIVIO CONTENENTE STATISTICHE'; TITLE2 'DESCRITTIVE, A PARTIRE DA UN ARCHIVIO SAS DI DETTAGLIO'; PROC PRINT DATA=DATISAS.ESTRATTO; FORMAT NVALORI TOTVEND MEDIAVEN 12.2; RUN;

Figura 7.7: Uso della PROC MEANS per creare un archivio estratto contente statistiche descrittive

CREAZIONE DI UN ARCHIVIO CONTENENTE STATISTICHE DESCRITTIVE, A PARTIRE DA UN ARCHIVIO SAS DI DETTAGLIO OBS NOMERAP NVALORI MEDIAVEN 1 2 Artale Banti 9.00 9.00 TOTVEND

196333.33 1767000.00 378777.78 3409000.00

Figura 7.8: Output prodotto dal programma di figura 7.7 Queste variabili sono presenti nella dichiarazione OUTPUT, associate rispettivamente alle parole chiave N=, SUM= e MEAN= indicanti le statistiche descrittive richieste; inoltre la parola chiave OUT= segnala alla procedura MEANS il nome dell'archivio da creare.

277

7.3.

Uso della procedura FREQ

Molto spesso gli studiosi di varie discipline, ed in particolare quelli di Scienze Sociali, si trovano nella necessit di elaborare dati contenuti in questionari predisposti per una elaborazione a mezzo del calcolatore. Supponiamo di dover elaborare semplici questionari, tipo quello mostrato in figura 7.9.

1. Et: 2. Sesso: 3. Stato Civile: 4. Titolo di studio:

Questionario Numero

5. Secondo te l'inquinamento rappr un reale pericolo per le sorti nere umano ? 6. Sarebbe necessario incrementare investimenti pubblici per migli le condizioni di vita nelle gra citt ? 7. Sei a conoscenza di particolari ambientali nei luoghi dove vivi 8. Se SI, elenca l'indirizzo e i p

esenta del ge-

gli orare ndi

disastri ? roblemi:

Figura 7.9: Schema di questionario-tipo L'intervistato deve rispondere alle domande secondo lo schema di codifica mostrato in figura 7.10. Al fine di elaborare i dati dei questionari si dovr prima creare un archivio SAS contenente tante osservazioni quanti sono i questionari compilati. Ciascuna osservazione conterr tante variabili quante sono le domande del questionario tipo (nel nostro caso 8) pi una, rappresentante il numero progressivo del questionario. 278

Il passo di DATA mostrato in figura 7.11 crea l'archivio denominato DATISAS.QUESTION mostrato, in parte, in figura 7.12. Ciascun questionario stato codificato mediante 6 righe di ingresso e la tecnica di lettura adottata permette di leggere le registrazioni in ingresso a gruppi di 6, scrivendo una osservazione in uscita per ciascun gruppo.
DOMANDA 1. Et 2. Sesso 3. Stato Civile CODICE/VALORE Et del soggetto 1=Maschio 2=Femmina 1=Scapolo/Nubile 2=Maritato/a 3=Divorziato/a 4=Vedovo/a 1=Nessuno 2=Licenza 3=Licenza 4=Licenza 5=Diploma 1=Si 2=No Risposta libera

4. Titolo di studio

elementare media inferiore media superiore di laurea

5. - 6. e 7. 8.

Figura 7.10: Schema di codifica Ottenuto l'archivio DATISAS.QUESTION, si pu cominciare l'analisi dei dati richiedendo, mediante il passo di figura 7.13, una tabella che mostri i valori assunti da alcune variabili quali: ETA, SESSO, STATOCIV, TITSTUD, RISP5, RISP6 e RISP7, al fine di individuare, ad esempio, la presenza di valori mancanti o invalidi. La PROC FREQ produce, per ciascuna variabile elencata nella dichiarazione TABLES, la lista dei suoi valori e per ciascuno di essi riporta la frequenza (assoluta e cumulativa) e la percentuale (assoluta e cumulativa) rispetto al totale dei valori della variabile in questione, come mostrato in figura 7.14. La dichiarazione TABLES del programma di figura 7.13 presenta una particolare sintassi che comodo utilizzare, soprattutto, quando le variabili coinvolte nell'analisi sono tante, e si vuole evitare di doverle elencare tutte. In questi casi, possibile utilizzare un forma pi concisa del tipo: TABLES variabile_A -- variabile_B indicante che dovranno essere prese in considerazione tutte le variabili dell'archivio SAS, da variabile_A sino a variabile_B.

279

OPTIONS PS=40 LS=72; DATA DATISAS.QUESTION; INPUT #1 NUMQUEST 1-3 ETA 4-5 SESSO 6 STATOCIV 7 TITSTUD 8 RISP5 9 RISP6 10 RISP7 11 #2 RISP8R1 $ 1-80 #3 RISP8R2 $ 1-80 #4 RISP8R3 $ 1-80 #5 RISP8R4 $ 1-80 #6 RISP8R5 $ 1-80; CARDS; 00125114110 . . . . . 00234225111 LOCALITA' "ACQUA MARCIA" - FALDA INQUINATA DA SCARICHI INDUSTRIALI LOCALITA' "BELLA VISTA" - MONTAGNA EROSA CON FENOMENI DI DEGRADO BOSCHIVO . . . 00322112111 LOCALITA' "VECCHIA MARINA" - BALNEAZIONE IMPOSSIBILE-COLIBATTERI FECALI . . . . 00430111000 . . . . . 00542234110 . . . . . ............ proseguono i dati .............. ;

Figura 7.11: Passo di creazione dell'archivio DATISAS.QUESTION In generale, la dichiarazione TABLES indica la forma della tabella desiderata; si possono ottenere tabelle a n dimensioni. Esempi di dichiarazione TABLES:
TABLES variabile(i) / [opzioni];

produrr una tabella ad 1 dimensione:


TABLES variabile1*variabile2 / [opzioni];

produrr una tabella a 2 dimensioni: / [opzioni]; produrr una tabella a 3 dimensioni. La tabella a 3 dimensioni ottenuta come n tabelle a due dimensioni, dove n il numero di
TABLES variabile1 *variabile2 *variabile3

280

valori diversi assunti dalla variabile1;


TABLES (variabile1 variabile2)*variabile3 / [opzioni];

produrr due tabelle a 2 dimensioni, ed equivalente a:


TABLES variabile1 *variabile3 / [opzioni];

TABLES variabile2 *variabile3 / [opzioni];

Si riportano di seguito alcune delle numerose possibilit della procedura FREQ e i nomi delle relative opzioni (indicati tra parentesi) da citare nella dichiarazione TABLES. Mediante la TABLES possibile: richiedere l'interpretazione di valori mancanti come una classe particolare, valida ai fini dell'analisi (MISSING); sopprimere la stampa delle frequenze (NOFREQ), delle percentuali (NOPERC), delle cumulative, frequenze e percentuali (NOCUM); sopprimere le percentuali di colonna (NOCOL) e/o di riga (NOROW); richiedere la stampa, per ogni cella della tabella, del test di omogeneit o di indipendenza CHI-SQUARE, assieme ad altre misure di associazione relative (CHISQ); richiedere, per ogni cella della tabella, la stampa del valore atteso nell'ipotesi di indipendenza o di omogeneit dei dati (EXPECTED).

SAS Data Set: DATISAS.QUESTION Command ===> OBS 1 2 3 4 5 Command ===> OBS 1 2 3 4 5 RISP8R1 NUMQUEST 1 2 3 4 5 ETA SESSO

Observations First Last TITSTUD 1 5

STATOCIV 1 2 1 1 3

25 1 34 2 22 1 30 1 42 2 SAS Data Set: DATISAS.QUESTION

4 5 2 1 4 Observations First 1 Last 5

LOCALITA' "ACQUA MARCIA" - FALDA INQUINATA DA SCARICHI INDUSTRIALI LOCALITA' "VECCHIA MARINA" - BALNEAZIONE IMPOSSIBILE-COLIBATTERI FECALI

Figura 7.12: Contenuto parziale dell'archivio DATISAS.QUESTION 281

OPTIONS LS=132 PS=60; PROC FREQ DATA=DATISAS.QUESTION; TABLES ETA--RISP7;

Figura 7.13: Uso della PROC FREQ per listare i valori assunti da alcune variabili dell'archivio in esame

CUMULATIVE CUMULATIVE ETA FREQUENCY PERCENT FREQUENCY PERCENT -------------------------------------------------22 1 20.0 1 20.0 25 1 20.0 2 40.0 30 1 20.0 3 60.0 34 1 20.0 4 80.0 42 1 20.0 5 100.0 CUMULATIVE CUMULATIVE SESSO FREQUENCY PERCENT FREQUENCY PERCENT ---------------------------------------------------1 3 60.0 3 60.0 2 2 40.0 5 100.0 CUMULATIVE CUMULATIVE STATOCIV FREQUENCY PERCENT FREQUENCY PERCENT ----------------------------------------------------1 3 60.0 3 60.0 2 1 20.0 4 80.0 3 1 20.0 5 100.0 CUMULATIVE CUMULATIVE TITSTUD FREQUENCY PERCENT FREQUENCY PERCENT ----------------------------------------------------1 1 20.0 1 20.0 2 1 20.0 2 40.0 4 2 40.0 4 80.0 5 1 20.0 5 100.0 CUMULATIVE CUMULATIVE RISP5 FREQUENCY PERCENT FREQUENCY PERCENT ---------------------------------------------------0 1 20.0 1 20.0 1 4 80.0 5 100.0 CUMULATIVE CUMULATIVE RISP6 FREQUENCY PERCENT FREQUENCY PERCENT ---------------------------------------------------0 1 20.0 1 20.0 1 4 80.0 5 100.0 CUMULATIVE CUMULATIVE RISP7 FREQUENCY PERCENT FREQUENCY PERCENT ---------------------------------------------------0 3 60.0 3 60.0 1 2 40.0 5 100.0

Figura 7.14: Output prodotto dal passo di figura 7.13

282

Affinch le tabelle prodotte mediante la procedura FREQ risultino di pi facile lettura e comprensione, si definiscono dei formati di scrittura che verranno assegnati alle variabili di cui si desidera la stampa. Il programma mostrato in figura 7.15 si compone di due passi; nel primo vengono definiti i formati: SESSOFMT, STCIVFMT, TISTUFMT, che sono assegnati rispettivamente alle variabili SESSO, STATOCIV e TITSTUD, ed il formato SINOFMT assegnato alle variabili RISP5, RISP6 e RISP7.
PROC FORMAT; VALUE SESSOFMT 1='MASCHIO' 2='FEMMINA' OTHER='CODICE ERRATO'; VALUE STCIVFMT 1='SCAPOLO/NUBILE' 2='MARITATO/A' 3='DIVORZIATO/A' 4='VEDOVO/A' OTHER='CODICE ERRATO'; VALUE TISTUFMT 1='NESSUNO' 2='LIC. ELEMENTARE' 3='LIC. MEDIA INF.' 4='LIC. MEDIA SUP.' 5='DIP. LAUREA' OTHER='CODICE ERRATO'; VALUE SINOFMT 1='SI' 0='NO' OTHER='CODICE ERRATO';

PROC FREQ DATA=DATISAS.QUESTION; TABLES ETA*SESSO; FORMAT SESSO SESSOFMT.; RUN;

Figura 7.15: Uso della procedura FORMAT e dell'istruzione FORMAT Sebbene le regole sintattiche che regolano la creazione dei formati si suppongano gi note, occorre ricordare che sempre bene racchiudere tra apici le stringhe alla destra del segno uguale. Nel secondo passo viene richiamata la procedura FREQ e mediante la dichiarazione TABLES viene richiesta una tabella a due dimensioni riportante in verticale la variabile ETA ed in orizzontale la variabile SESSO. La dichiarazione FORMAT assegna alla variabile SESSO il formato SESSOFMT definito nel passo precedente; detta assegnazione sar valida solo nel contesto della PROC FREQ. La tabella prodotta come risultato mostrata in figura 7.16.

283

Come si pu notare dall'uscita prodotta, la procedura FREQ inserisce, sul margine sinistro in alto di ciascuna tabella, una legenda che indica brevemente il significato dei numeri inseriti in ogni casella della tabella, all'incrocio di ciascun valore della variabile verticale con ciascuno della variabile orizzontale. Ad esempio, il primo numero (1) rappresenta la frequenza (FREQUENCY), nel senso che: c' una sola osservazione dell'archivio per la quale le variabili ETA e SESSO assumono rispettivamente i valori 22 e MASCHIO. Il secondo numero (20.00) rappresenta la percentuale (PERCENT) rispetto al totale delle osservazioni.

TABLE OF ETA BY SESSO ETA SESSO

FREQUENCY| PERCENT | ROW PCT | COL PCT |MASCHIO |FEMMINA | | | | TOTAL ---------+--------+--------+ 22 | 1 | 0 | 1 | 20.00 | 0.00 | 20.00 | 100.00 | 0.00 | | 33.33 | 0.00 | ---------+--------+--------+ 25 | 1 | 0 | 1 | 20.00 | 0.00 | 20.00 | 100.00 | 0.00 | | 33.33 | 0.00 | ---------+--------+--------+ 30 | 1 | 0 | 1 | 20.00 | 0.00 | 20.00 | 100.00 | 0.00 | | 33.33 | 0.00 | ---------+--------+--------+ 34 | 0 | 1 | 1 | 0.00 | 20.00 | 20.00 | 0.00 | 100.00 | | 0.00 | 50.00 | ---------+--------+--------+ 42 | 0 | 1 | 1 | 0.00 | 20.00 | 20.00 | 0.00 | 100.00 | | 0.00 | 50.00 | ---------+--------+--------+ TOTAL 3 2 5 60.00 40.00 100.00

Figura 7.16: Output prodotto dal programma di figura 7.15 Il terzo numero (100.00) fornisce la percentuale di riga (ROW PCT), ed indica che i soggetti di sesso maschile rappresentano il 100% dei soggetti di 22 anni di et. Infine, il quarto numero (33.33) rappresenta la percentuale di colonna (COL PCT), ed indica che i soggetti aventi 22 anni rappresentano il 33.33% rispetto al totale dei soggetti maschi. 284

I passi mostrati nelle figure 7.17 e 7.19 illustrano due ulteriori esempi di richiamo della PROC FREQ per produrre tabelle a 2 dimensioni come quelle delle figure 7.18 e 7.20.
TITLE 'INCROCIO TRA L''ETA'' E LA DOMANDA N.5'; TITLE2 'SECONDO TE L''INQUINAMENTO RAPPRESENTA UN REALE PERICOLO'; TITLE3 'PER LE SORTI DEL GENERE UMANO ?'; PROC FREQ DATA=DATISAS.QUESTION; TABLES ETA*RISP5; FORMAT RISP5 SINOFMT.; RUN;

Figura 7.17 : Esempio d'uso della PROC FREQ

INCROCIO TRA L'ETA' E LA DOMANDA N.5 SECONDO TE L'INQUINAMENTO RAPPRESENTA UN REALE PERICOLO PER LE SORTI DEL GENERE UMANO ? TABLE OF ETA BY RISP5 ETA RISP5

FREQUENCY| PERCENT | ROW PCT | COL PCT |NO |SI | | | | TOTAL ---------+--------+--------+ 22 | 0 | 1 | 1 | 0.00 | 20.00 | 20.00 | 0.00 | 100.00 | | 0.00 | 25.00 | ---------+--------+--------+ 25 | 0 | 1 | 1 | 0.00 | 20.00 | 20.00 | 0.00 | 100.00 | | 0.00 | 25.00 | ---------+--------+--------+ 30 | 1 | 0 | 1 | 20.00 | 0.00 | 20.00 | 100.00 | 0.00 | | 100.00 | 0.00 | ---------+--------+--------+ 34 | 0 | 1 | 1 | 0.00 | 20.00 | 20.00 | 0.00 | 100.00 | | 0.00 | 25.00 | ---------+--------+--------+ 42 | 0 | 1 | 1 | 0.00 | 20.00 | 20.00 | 0.00 | 100.00 | | 0.00 | 25.00 | ---------+--------+--------+ TOTAL 1 4 5 20.00 80.00 100.00

Figura 7.18: Output prodotto dal passo di figura 7.17

285

TITLE 'INCROCIO TRA SESSO E LA DOMANDA N.6'; TITLE2 'SAREBBE NECESSARIO INCREMENTARE GLI INVESTIMENTI PUBBLICI'; TITLE3 'PER MIGLIORARE LE CONDIZIONI DI VITA NELLE GRANDI CITTA''?; PROC FREQ DATA=DATISAS.QUESTION; TABLES SESSO*RISP6; FORMAT SESSO SESSOFMT. RISP6 SINOFMT.; RUN;

Figura 7.19: Esempio d'uso della PROC FREQ


INCROCIO TRA SESSO E LA DOMANDA N.6 SAREBBE NECESSARIO INCREMENTARE GLI INVESTIMENTI PUBBLICI PER MIGLIORARE LE CONDIZIONI DI VITA NELLE GRANDI CITTA'? TABLE OF SESSO BY RISP6 SESSO FREQUENCY PERCENT ROW PCT COL PCT RISP6

| | | |NO |SI | | | | TOTAL --------------+--------+--------+ MASCHIO | 1 | 2 | 3 | 20.00 | 40.00 | 60.00 | 33.33 | 66.67 | | 100.00 | 50.00 | --------------+--------+--------+ FEMMINA | 0 | 2 | 2 | 0.00 | 40.00 | 40.00 | 0.00 | 100.00 | | 0.00 | 50.00 | --------------+--------+--------+ TOTAL 1 4 5 20.00 80.00 100.00

Figura 7.20: Output prodotto dal passo di figura 7.19

7.4.

Uso della procedura CORR

Tra le statistiche che vengono usate per verificare se esiste una relazione lineare tra due variabili numeriche continue esiste il coefficiente di correlazione di Pearson, spesso chiamato solamente coefficiente di correlazione. Il coefficiente di correlazione definito da una formula che produce un numero che pu variare tra -1 e +1. Quando si in presenza di un coefficiente di correlazione positivo vicino all'unit si pu affermare che esiste una relazione positiva tra le due variabili in esame, nel senso che all'aumentare (diminuire) dei valori dell'una anche i valori dell'altra tendono ad aumentare (diminuire). Un coefficiente vicino allo zero non implica la conclusione che non esiste alcuna relazione tra le due variabili, ma significa piuttosto che 286

non c' una relazione di tipo lineare tra di esse. Infine un valore negativo vicino a -1 indica una relazione inversa tra le due variabili cio, quando i valori dell'una crescono, quelli dell'altra tendono a decrescere e viceversa. Come esempio, si desidera verificare se esiste una relazione tra l'altezza ed il peso di soggetti di un campione opportunamente scelto e contenuto nell'archivio SAS di figura 7.21. Il passo di figura 7.22 produce l'output di figura 7.23.
LISTA DEI DATI USATI NELL'ESPERIMENTO OBS SESSO ALTEZZA PESO 1 2 3 4 5 6 7 8 F M F M M F M F 155 170 160 180 183 167 185 165 48 72 55 85 79 58 92 60

Figura 7.21: Archivio DATISAS.ALTPESO


TITLE 'CALCOLO DEL COEFFICIENTE DI CORRELAZIONE'; PROC CORR DATA=DATISAS.ALTPESO; VAR ALTEZZA PESO; RUN;

Figura 7.22: Esempio d'uso della procedura CORR Dall'output di figura 7.23 notiamo che il coefficiente di correlazione tra le variabili ALTEZZA e PESO 0.96428; questo valore indica l'esistenza di una correlazione positiva tra le variabili prese in esame. Tra i dati forniti in uscita dalla procedura CORR c' anche la probabilit associata al coefficiente di correlazione fornito. Detto numero, che in questo caso 0.0001, ci dice qual' la probabilit di ottenere un coefficiente di correlazione campionario grande quanto o, addirittura pi grande, di quello ottenuto quando le variabili in esame non hanno nessuna correlazione. In questo caso detta probabilit decisamente bassa e questo avvalora ulteriormente l'esistenza di una relazione lineare tra le due variabili in gioco. I testi di statistica ricordano che la significativit del coefficiente di correlazione dipende anche dalla dimensione del campione e che, per grandi campioni, anche un coefficiente di correlazione non molto grande potrebbe essere significativo. 287

CALCOLO DEL COEFFICIENTE DI CORRELAZIONE VARIABLE MAXIMUM ALTEZZA 185.0000 PESO 92.0000 N MEAN STD DEV SUM MINIMUM

8 8

170.6250 68.6250

11.01865 15.72929

1365.000 549.000

155.0000 48.0000

PEARSON CORRELATION COEFFICIENTS / PROB > |R| UNDER H0:RHO=0 / N = 8 ALTEZZA PESO

ALTEZZA

1.00000 0.0000 0.96428 0.0001

0.96428 0.0001 1.00000 0.0000

PESO

Figura 7.23: Output prodotto dal programma di figura 7.22 Avendo scoperto che il coefficiente di correlazione significativamente diverso da zero, appropriato cercare di vedere come si distribuiscono i dati del problema, scegliendo una opportuna rappresentazione grafica, per esempio graficando i valori delle due variabili come mostrato in figura 7.24 che produce l'output di figura 7.25. L'analisi della figura 7.25 denota una chiarissima correlazione tra le due variabili e spesso questo tipo di analisi visiva permette di individuare i punti estremi (outlyers) che sono responsabili della differenza tra il coefficiente di correlazione atteso e quello calcolato dalla procedura. In questo modo possibile escludere detti punti dall'analisi.
TITLE 'VERIFICA MEDIANTE PLOT DEI DATI DELL''ESPERIMENTO'; PROC PLOT DATA=DATISAS.ALTPESO; PLOT ALTEZZA*PESO; RUN;

Figura 7.24: Esempio d'uso della procedura PLOT per visualizzare dati dell'esperimento

7.5 Uso della procedura REG


A questo punto ci si potrebbe chiedere: possibile predire l'altezza di un soggetto dato il suo peso? Per rispondere a questa domanda occorre trovare una relazione matematica che leghi i valori del peso a quelli dell'altezza; se si osserva il grafico di figura 7.25 si nota che la relazione tra le due variabili approssimativamente lineare, cio possibile disegnare una linea retta unendo la maggior parte dei punti del grafico. 288

VERIFICA MEDIANTE PLOT DEI DATI DELL'ESPERIMENTO PLOT OF ALTEZZA*PESO LEGEND: A = 1 OBS, B = 2 OBS, ETC.

ALTEZZA | | 185 + A | | A | 180 + A | | | 175 + | | | 170 + A | | A | 165 + A | | | 160 + A | | | 155 + A | --+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 PESO

Figura 7.25: Output prodotto dal programma di figura 7.24 Affinch la previsione risulti la migliore possibile, occorrer disegnare quella retta, tra le tante possibili, i cui punti distano da quelli sperimentali il meno possibile. Matematicamente si pu risolvere questo problema individuando la retta che meglio interpola i punti sperimentali dati. La distanza verticale di ciascun punto sperimentale dal corrispondente punto situato sulla retta interpolante chiamato: residuo. La procedura REG pu essere usata per stimare i due parametri caratteristici della retta interpolante: il coefficiente angolare e l'intercetta con l'asse delle ordinate; detta procedura usa il metodo dei minimi quadrati per individuare la retta di regressione, per la quale diventa minima la somma dei quadrati dei residui. Il passo mostrato in figura 7.26 serve per invocare la procedura REG; si nota la presenza della dichiarazione MODEL la cui sintassi : 289

MODEL <variabile dipendente> = <variabile indipendente>; La figura 7.27 illustra i risultati prodotti dalla procedura in questione, in particolare nella sezione PARAMETER ESTIMATES, possiamo leggere i valori dei due parametri cercati. L'equazione che descrive la retta di regressione desiderata :
ALTEZZA = (0.68)*(PESO) + (124.27)

PROC REG DATA=DATISAS.ALTPESO; MODEL ALTEZZA=PESO; TITLE 'CALCOLO DEI COEFFICIENTI DELLA RETTA DI REGRESSIONE'; RUN;

Figura 7.26: Esempio d'uso della procedura REG

CALCOLO DEI COEFFICIENTI DELLA RETTA DI REGRESSIONE DEP VARIABLE: ALTEZZA ANALYSIS OF VARIANCE SUM OF SQUARES 790.24613 59.62887044 849.87500 3.152482 170.625 1.847609 MEAN SQUARE 790.24613 9.93814507

SOURCE MODEL ERROR C TOTAL

DF 1 6 7

F VALUE 79.516

PROB>F 0.0001

ROOT MSE DEP MEAN C.V.

R-SQUARE ADJ R-SQ

0.9298 0.9181

PARAMETER ESTIMATES PARAMETER ESTIMATE 124.26907 0.67549621 STANDARD ERROR 5.31662572 0.07575205 T FOR H0: PARAMETER=0 23.374 8.917

VARIABLE INTERCEP 0.0001 PESO 0.0001

DF 1 1

PROB > |T|

Figura 7.27: Output del passo di figura 7.26

290

8. Il linguaggio SAS-macro

8.1.

Introduzione al linguaggio macro

Nella presentazione del sistema SAS svolta fino a questo punto abbiamo considerato i passi di un programma come dei blocchi separati che individualmente concorrono al risultato finale. La comunicazione tra passi diversi effettuata solo mediante lo scambio di archivi. Inoltre l'interazione con il sistema operativo, vista fino ad ora, stata molto limitata. Con gli strumenti considerati infatti, una volta iniziato un programma, i passi si susseguono nell'ordine in cui sono stati scritti senza nessuna possibilit di ripetere pi volte uno stesso passo o di saltarne uno, al determinarsi di certe condizioni. La scrittura di un programma inoltre non pu essere fatta in forma parametrica, con la possibilit cio di permettere certe variazioni dipendenti dal risultato di una elaborazione di un passo precedente. Per aiutarci nella scrittura di un programma e per risolvere i problemi sopra descritti stato introdotto il linguaggio SAS-macro. Lo scopo di questo capitolo quello di fornire solo un primo approccio all'utilizzo del linguaggio SAS-macro senza entrare nel merito di un utilizzo sofisticato di questo strumento. Con la lettura di questo capitolo per, dovrebbe risultare possibile imparare a scrivere programmi che fanno un corretto uso delle macro. Con il linguaggio SAS-macro potremo: eseguire i passi di un programma condizionandoli al verificarsi di certe condizioni che dipendono da passi precedenti o dal sistema operativo; ottenere informazioni dal sistema operativo senza abbandonare il sistema SAS ed eventualmente passarle a passi di DATA o di PROC; sviluppare applicazioni interattive, sia in line mode che in full screen con menu guida; generare dichiarazioni SAS dipendenti dai dati che vengono elaborati; 291

scambiare informazioni tra i vari passi; generare automaticamente dichiarazioni SAS che si ripetono. Il linguaggio SAS-macro un linguaggio di programmazione che ha una sintassi che risulta abbastanza semplice per chi gi conosce quella del linguaggio SAS. Infatti i due linguaggi, pur non avendo la stessa sintassi (in quanto devono assolvere a compiti diversi e debbono farsi riconoscere dal sistema), hanno in comune lo stesso stile e lo stesso modo di presentarsi. E' bene sottolineare che i linguaggi SAS e macro, hanno finalit diverse. Il primo elabora dati mentre il secondo tratta solamente stringhe (es.: dichiarazioni SAS o parti di esse) che usualmente formeranno, come risultato finale, interi passi di DATA o di PROC, oppure parti di essi.

8.2.

Concetti generali

Abbiamo detto che un programma SAS costituito da un insieme di passi di DATA e/o di PROC. Il supervisore SAS si preoccupa, per prima cosa, di separare i passi e poi di eseguirli nell'ordine in cui essi appaiono. Le parole utilizzate in questa fase per riconoscere i passi sono: DATA, PROC, CARDS, CARDS4, PARMCARDS, ENDSAS e RUN. Una schematizzazione del funzionamento del sistema riportata in figura 8.1.

Programma SAS composto da vari passi SUPERVISORE SAS DATA STEP PROC STEP

Figura 8.1: Diagramma di flusso del sistema SAS Il linguaggio macro: adatto a elaborare stringhe (sequenze ordinate di caratteri) che spesso formeranno istruzioni del linguaggio SAS o parte di esse;

292

trattato da una parte apposita del sistema SAS chiamata "analizzatore macro" che ha il compito di risolvere ed eseguire il linguaggio macro prima della fase di compilazione nei passi di DATA, o della fase di preparazione e controllo formale (detta: fase di "parser") nei passi di PROC. Quando si usa il linguaggio macro, il testo del programma viene sottomesso all'esame dell'analizzatore macro se il supervisore incontra in esso dei riferimenti al linguaggio macro. Affinch il supervisore attivi l'analizzatore macro, l'utente deve inviare il comando "SAS" seguito dall'opzione "MACRO", al momento in cui si avvia la sessione (a sessione avviata detta opzione non accettata). Il processo di elaborazione pu essere schematizzato come in figura 8.2:

Programma SAS composto da vari passi SUPERVISORE SAS ANALIZZATORE MACRO

DATA STEP
(Compilatore)

PROC STEP
(Parser)

Figura 8.2: Le componenti del sistema SAS Le principali componenti sulle quali opera il linguaggio macro sono: le macro-variabili; le macro.

8.3. Il linguaggio SAS-macro e le macrovarabili


Le variabili usate in ambito del linguaggio macro vengono definite "macro-variabili". Esse possono essere suddivise in due tipi: automatiche (cio definite dal supervisore SAS); 293

definite dall'utente. Le regole da seguire nella scrittura dei nomi delle macro-variabili sono le stesse che regolano la scrittura dei nomi delle variabili SAS (lunghezza massima 8 caratteri, ecc.). Naturalmente possibile assegnare nomi scelti dall'utente alle macro-variabili del secondo tipo, mentre quelle automatiche hanno gi un nome stabilito. In generale le macro-variabili seguono le seguenti regole: i riferimenti a macro-variabili devono essere fatti anteponendo al nome della macro-variabile il carattere "&" ("e" commerciale) e, facoltativamente, posponendo il carattere "." (punto); il sistema SAS sostituir i riferimenti alle macro-variabili con il loro valore corrente (tale valore pu essere anche vuoto); la lunghezza del valore di una macro-variabile pu variare da zero al massimo stabilito per la sessione SAS (tale massimo dipende dalla installazione, ma comunque non mai inferiore a 1024 caratteri). Alcune caratteristiche delle macro-variabili automatiche sono le seguenti: sono sempre accessibili al programmatore (il sistema SAS le definisce ad inizio sessione); possono essere utilizzate in qualsiasi punto del programma SAS; i valori sono normalmente assegnati dal sistema SAS; in alcuni casi l'utente pu assegnare valori alle macro-variabili automatiche. Segue un parziale elenco di macro-variabili automatiche con una breve descrizione del loro contenuto. Le macro-variabili indicate con un asterisco sono utilizzabili in sola lettura. SYSDATE* SYSDAY* SYSTIME* SYSENV* indicano rispettivamente: la data ( es.: 22JAN87 ), il giorno della settimana (es.: THURSDAY) e il tempo (es.: 10:45) in cui inizia l'esecuzione del programma SAS; modo di esecuzione: pu valere "FORE" (che sta per FOREGROUND - conversazionale) o "BACK" (che sta per BACKGROUND - modo batch); nome del sistema operativo usato (OS, CMS, DOS, ecc.); 294

SYSSCP*

SYSVER* SYSJOBID*

versione del sistema SAS in uso (es.: 5.16); nome della "userid" per il TSO o ICCF, nome della macchi- na virtuale per il CMS o nome del programma se OS o DOS batch, ecc; nome dell'area dove sono memorizzati i valori forniti in eccesso in risposta ad una dichiarazione %INPUT; nome del dispositivo grafico in uso (specificato con una GOPTIONS o in modo interattivo); nome dell'ultimo archivio SAS creato. Il suo contenuto simile a quello della variabile automatica SAS _LAST_ (es.: 'WORK DATA1 '); ultimo codice di ritorno impostato dal linguaggio macro (es: 0, 1117, 1350, ecc.); finestra del DMS attiva attualmente (L=LOG; O=OUTPUT; P=PROGRAM; );

SYSBUFFR SYSDEVIC SYSDSN

SYSRC

DMSMSGID numero dell'ultimo messaggio fornito dal DMS; DMSWID

DMSLMSG testo del messaggio corrente (che appare sotto la riga DMSPMSG di Command) relativo rispettivamente alla finestra di DMSOMSG LOG, di PROGRAM o di OUTPUT; DMSLFK1 ... contengono rispettivamente i valori correnti dei tasti funzioDMSLFK24 nali PFK1-PFK24 relativi alla finestra LOG; DMSPFK1 ... contengono rispettivamente i valori correnti dei tasti funzioDMSPFK24 nali PFK1-PFK24 relativi alla finestra PROGRAM; DMSOFK1 ... contengono rispettivamente i valori correnti dei tasti funzioDMSOFK24 nali PFK1-PFK24 relativi alla finestra OUTPUT. Consideriamo di voler definire un titolo che stampi la data attuale dell'esecuzione del programma. Poich il sistema SAS non prevede che i titoli abbiano una parte variabile, dovremo usare il linguaggio macro. Nell'esempio che segue stata introdotta la macro-variabile automatica &SYSDATE nella dichiarazione TITLE.
PROC PRINT; TITLE 'Fatture aggiornate al '&SYSDATE; RUN;

Nell'ipotesi che il passo di DATA sia stato eseguito il 15/9/88 la macro-variabile SYSDATE viene sostituita con il proprio valore; otteniamo pertanto il seguente risultato:

295

Fatture aggiornate al 15SEP88 OBS 1 2 FATTURA 325 456 IMPORTO 123000000 110000000 DATA 10/06/88 11/07/88

Nell'utilizzare la macro-variabile, abbiamo fatto attenzione a non racchiuderla all'interno degli apici in quanto il linguaggio macro non prevede di analizzare il testo che si trova racchiuso tra singoli apici. Se infatti scriviamo:
PROC PRINT; TITLE 'Fatture aggiornate al &SYSDATE'; RUN;

la macro-variabile SYSDATE che si trova all'interno degli apici non viene riconosciuta come tale, ma come parte del titolo. Otteniamo perci il seguente risultato che sicuramente non corrisponde a quanto richiesto:
Fatture aggiornate al &SYSDATE OBS 1 2 FATTURA 325 456 IMPORTO 123000000 110000000 DATA 10/06/88 11/07/88

Avremmo potuto ottenere ugualmente il risultato corretto utilizzando il carattere "doppio apice" come mostrato nell'esempio che segue:
OPTIONS DQUOTE; PROC PRINT; TITLE "Fatture aggiornate al &SYSDATE"; RUN;

che ci consente di ottenere:


Fatture aggiornate al 15SEP88 OBS 1 2 FATTURA 325 456 IMPORTO 123000000 110000000 DATA 10/06/88 11/07/88

Con l'utilizzo di doppi apici possibile specificare il singolo apice come apostrofo o come accento (es.: TITLE "Iscritti all'Universita'");

8.4. Macro-istruzione %LET e macrofunzioni %STR e %NRSTR


Consideriamo ora le macro-variabili definite dall'utente. Per definirle e per assegnare loro un valore si utilizza la macro-istruzione di 296

assegnazione %LET la cui sintassi : %LET nome-macro-variabile = valore; La parola %LET una parola chiave che indica l'inizio della macroistruzione. Segue il nome della macro-variabile alla quale vogliamo assegnare il valore. Se la macro-variabile compare per la prima volta essa viene definita. Di seguito va scritto il segno "=" (uguale) ed il valore che si deve assegnare. Per valore si intende una qualsiasi stringa di caratteri. Esempio:
%LET A=15 Settembre 1988; %LET B=LIB.DATI1; OPTIONS DQUOTE; PROC PRINT DATA=&B; TITLE "Fatture aggiornate al &A"; RUN;

Nelle macro-istruzioni %LET dell'esempio precedente, vengono assegnati alcuni valori che poi saranno sostituiti ai nomi delle macrovariabili che compaiono nel testo del programma. I riferimenti alle macro-variabili vengono fatti anteponendo ai nomi il carattere &, per distinguerle dalle altre parole SAS. Il compilatore riceve il testo del programma dopo che le sostituzioni delle macro-variabili sono avvenute e non distingue se il testo stato prodotto da sostituzioni del linguaggio macro o scritto direttamente. Le istruzioni precedenti producono il programma:
OPTIONS DQUOTE; PROC PRINT DATA=LIB.DATI1; TITLE "Fatture aggiornate al 15 Settembre 1988"; RUN;

Di seguito sono riportate le regole che devono essere osservate quando si usa la macro-istruzione %LET. Essa: definisce una macro-variabile con il nome indicato (se questa non esiste gi); assegna alle macro-variabili un valore; non richiede uso di apici per racchiudere il valore; se si usano apici, questi vengono considerati parte del valore; elimina eventuali spazi bianchi che precedono o seguono il valore. Il valore pu essere costituito da: un testo costante; riferimenti a macro-variabili; macro-funzioni (saranno trattate nel seguito); chiamate a macro (saranno trattate nel seguito).

297

La figura 8.3 illustra il meccanismo di assegnazione dei valori alle macro-variabili nei vari casi. Viene fatta l'ipotesi, valida anche negli altri esempi mostrati nelle figure seguenti, che le dichiarazioni %LET illustrate, vengano tutte eseguite una dopo l'altra.
%LET %LET %LET %LET %LET %LET %LET %LET %LET %LET %LET %LET %LET %LET %LET %LET %LET %LET %LET %LET %LET Macro - istruzione NOME=Fabio; NOME='Fabio'; NOME="Fabio"; COGNOME=Bianchi; NC=&NOME &COGNOME; NC=&NOME '&COGNOME'; NC='&NOME &COGNOME'; NC="&NOME &COGNOME"; NOME= Fabio ; NC=&NOME &COGNOME; UNO=1; X=N.=; Y=&X&UNO; Y=&X5; Y=&X.5; MEMBER=DATA1; LIB=WORK; SDS=&LIB&MEMBER; SDS=&LIB.&MEMBER; SDS=&LIB..&MEMBER; PASSO= PROC PRINT; RUN; Valore macro-variabile Fabio 'Fabio' "Fabio" Bianchi Fabio Bianchi; Fabio '&COGNOME' '&NOME &COGNOME' "Fabio Bianchi" Fabio Fabio Bianchi 1 N.= N.=1 &X5 (segnala errore) N.=5 DATA1 WORK WORKDATA1 WORKDATA1 WORK.DATA1 PROC PRINT

Figura 8.3: Assegnazione di valori a macro-variabili Anche il linguaggio macro prevede l'uso di macro-funzioni predefinite analogamente a quanto avviene nel sistema SAS. Il modo di richiamare le macro-funzioni del tutto analogo a quello usato nel sistema SAS; la sola differenza consiste nel fatto che le macro-funzioni devono essere richiamate facendo precedere il loro nome dal carattere "%" (percento). Molte macro-funzioni sono del tutto simili alle omonime funzioni SAS, sia nella forma che nel funzionamento. Non sempre per macro-funzioni utilizzate dal linguaggio macro sono presenti nel sistema SAS e viceversa. Per permettere il trattamento dei caratteri speciali quali, punto e virgola, spazio, ecc., si pu usare la macro-funzione %STR. I caratteri indicati come argomento della macro-funzione %STR perdono il loro significato sintattico e vengono considerati facenti parte del valore. Fanno eccezione a questa regola i caratteri "&" e "%" sui quali la macro-funzione %STR non ha alcun effetto. Sono riportati nella figura 8.4 alcuni esempi di utilizzo della %STR. 298

%LET %LET %LET %LET %LET %LET

Macro - istruzione NOME=%STR (Fabio); COGNOME=%STR ( Bianchi); NC=&NOME&COGNOME; NC=%STR(&NOME; &COGNOME;); PASSO= %STR(PROC PRINT; RUN;); PASSO= PROC PRINT%STR(;)RUN%STR(;);

Valore macro-variab. Fabio (%STR non ha effetto) Bianchi Fabio Bianchi Fabio; Bianchi; PROC PRINT; RUN; PROC PRINT; RUN;

Figura 8.4: Uso della macro-funzione %STR Per permettere anche il trattamento dei due caratteri speciali "&" e "%", si deve usare la macro-funzione %NRSTR come mostrato in figura 8.5:
%LET Macro - istruzione NOME=%NRSTR (Fabio); Valore risultante Fabio (%NRSTR non ha effetto) Bianchi Fabio Bianchi &NOME; &COGNOME; PROC PRINT; RUN;

%LET %LET %LET %LET

COGNOME=%NRSTR( Bianchi); NC=&NOME&COGNOME; NC=%NRSTR(&NOME; &COGNOME;); PASSO= %NRSTR(PROC PRINT; RUN;);

Figura 8.5: Uso della macro-funzione %NRSTR Con la macro-istruzione %LET possibile fare assegnazioni indirette. La figura 8.6 fornisce alcuni esempi di assegnazione indiretta.
%LET %LET %LET %LET %LET %LET Macro - istruzione A=X; B=Y; &A=Buongiorno; &B=Buonasera; XY=Buonanotte; &A&B=ciao; Si risolve in... %LET A=X; %LET B=Y; %LET X=Buongiorno; %LET Y=Buonasera; %LET XY=Buonanotte; %LET XY=ciao;

Figure 8.6: Assegnazioni indirette Nel linguaggio macro esiste una regola secondo cui due caratteri "&" consecutivi vengono risolti in un singolo "&". Gli esempi riportati in figura 8.7 mostrano il trattamento dei doppi "&".

299

%LET %LET %LET %LET %LET

Macro - istruzione VET1=10; VET2=20; VET3=30; I=2; X=&VET&I;

%LET X=&&VET&I;

%LET %LET %LET %LET

DEVICE=IBM3279; &DEVICE=bene; T=La &DEVICE va &IBM3279; T=&DEVICE va &&&DEVICE;

Si risolve in... %LET VET1=10; %LET VET2=20; %LET VET3=30; %LET I=2; ... errore perch &VET non definito diviene: %LET X=&VET2; e successivamente: %LET X=20; %LET DEVICE=IBM3279; %LET IBM3279=bene; %LET T=La IBM3279 va bene; diviene: %LET T=IBM3279 va &IBM3279; e successivamente: %LET T=IBM3279 va bene;

Figura 8.7: Usi particolari delle assegnazioni Immaginiamo di avere le seguenti macro-istruzioni:
%LET A=PROC PRINT %STR (; RUN;); %LET B=&A; /*diventa %LET B=PROC PRINT; RUN;; */

Nella seconda assegnazione, dopo la sostituzione della macrovariabile A con il proprio valore, risulteranno due caratteri ";" consecutivi che potrebbero provocare un funzionamento indesiderato1 . Per inibire il funzionamento di caratteri speciali provenienti da sostituzioni dei contenuti di macro-variabili non si deve usare la macro-funzione %STR, ma la %QUOTE.
%LET A=PROC PRINT %STR (; RUN;); %LET B=%QUOTE(&A);

8.5.

Macro-istruzione %PUT

Consideriamo ora una seconda macro-istruzione, la %PUT, che ci permette di inviare messaggi sul LOG. Essa ha la seguente sintassi: %PUT testo; La macro-istruzione %PUT:

Quando non si seguono le regole di sintassi o di composizione del linguaggio non sempre otteniamo segnalazioni di errore o malfunzionamenti evidenti. In taluni casi possibile che il programma venga eseguito correttamente in determinati contesti, ma dia luogo a malfunzionamenti in altri.

300

provoca la stampa di testo sulla finestra LOG dopo aver risolto eventuali macro-variabili presenti in testo ( cio sostituito il loro nome con il relativo valore) ; pu stare in qualsiasi parte del programma SAS. Esempio:
%PUT Messaggio di prova;

oppure:
%LET TESTO=Messaggio; %PUT &TESTO di prova;

Dopo l'esecuzione delle %PUT vedremo il testo specificato ("Messaggio di prova") comparire sulla finestra LOG se usiamo il modo interattivo, o troveremo i messaggi nel file LOG, se usiamo il modo non interattivo o batch.

8.6.

Le macro

Si definisce "macro" un testo scritto tra le macro-istruzioni %MACRO e %MEND. Le macro possono essere composte da: una parte costante (un testo, che normalmente costituir parte di un programma SAS); assegnazioni di macro-variabili; riferimenti a macro-variabili; altre macro-istruzioni; macro-funzioni; chiamate di altre macro. Con la macro-istruzione %MACRO, oltre ad iniziare la macro, si definisce l'esistenza o meno di parametri (valori che vengono assegnati al momento del richiamo della macro); inoltre possibile indicare eventuali opzioni che verranno illustrate nel seguito. La sintassi la seguente:

%MACRO nome [(parametri)] [/ opzioni]; dove: nome pu essere un qualsiasi nome SAS con l'esclusione di quelli riservati (il linguaggio macro a differenza di quello SAS ha nomi riservati) riportati in figura 8.8. In CMS nome non pu superare i 7 caratteri; 301

i parametri sono opzionali; sono macro-variabili i cui valori vengono forniti al momento della chiamata; le possibili opzioni nella versione 5 del sistema SAS sono CMD e STMT, che verranno trattate nel seguito. La sintassi della macro-istruzione %MEND la seguente: %MEND [nome]; dove nome facoltativo; per ragioni di praticit, si consiglia di indicarlo sempre. Se presente, deve corrispondere a quello specificato sulla macro-istruzione %MACRO. Si pu richiamare una macro in qualsiasi parte del programma SAS semplicemente scrivendo il nome della macro preceduto dal carattere "%" (percento) ed eventualmente facendolo seguire da una coppia di parentesi entro cui vanno specificati i parametri. Esempio di richiamo di macro:
%LET P=PRINT; %LET SDS=DATI.INGRESSO; %MACRO M1; &P DATA=&SDS; RUN %MEND M1; ... PROC %M1 /* %M1 richiama la MACRO M1 */ ;

Il testo della macro, dopo che i riferimenti alle macro-variabili sono stati risolti, viene sostituito al richiamo della macro. In questo caso viene sostituito al posto di %M1 il seguente frammento di programma:
PRINT DATA=DATI.INGRESSO; RUN

Il programma finale generato (in grassetto la espansione della macro):


PROC PRINT DATA=DATI.INGRESSO; RUN ;

verr poi eseguito dal sistema SAS come un qualsiasi altro programma. Le parole "PROC" ed il carattere ";" che segue "RUN", non provengono dalla espansione della macro M1, ma erano specificate nel programma che richiama la macro. Eventuali errori SAS non vengono rilevati dalla parte del sistema SAS preposto al trattamento delle macro, ma verranno segnalati successivamente. 302

ABEND ABORT ACT ACTIVATE BY BQUOTE CLEAR CLOSE CMS COPY DEACT DEL DELETE DISPLAY DO EDIT ELSE END EVAL FILE GLOBAL

GO GOTO IF INC INCLUDE INDEX INFILE INPUT LET LOCAL LIST LISTM MACRO MEND METASYM NRBQUOTE NRQUOTE NRSTR ON OPEN PAUSE

PUT QSCAN QSUBSTR QUOTE QUPCASE RESOLVE RETURN RUN SAVE SCAN STOP STR SUBSTR THEN TO TSO UNQUOTE UNSTR UNTIL UPCASE WHILE

Figura 8.8: Parole che non possono essere usate come nomi di macro I parametri presenti all'interno delle macro possono essere definiti nella macro-istruzione %MACRO come: posizionali; a parola chiave. Qualora in una stessa macro si utilizzino entrambi i parametri, occorre specificare prima quelli posizionali e poi quelli con parola chiave. Un esempio di richiamo di una macro con parametri posizionali dato nel seguente frammento di programma.
%MACRO M1 (P, SDS); PROC &P DATA=&SDS; RUN; %MEND M1; ... %M1 (PRINT, DATI.INGRESSO) /* RICHIAMO DELLA MACRO M1 */ ...

Il testo della macro, dopo che i riferimenti alle macro-variabili ed ai parametri sono stati risolti, viene sostituito al richiamo della macro. Il primo valore specificato nella chiamata attribuito al parametro in prima posizione, il secondo valore al secondo, ecc.. In questo caso, alla chiamata della macro, viene sostituito il seguente frammento di programma: 303

... PROC PRINT DATA=DATI.INGRESSO; RUN; ...

Con il seguente richiamo:


... %M1 (, DATI.INGRESSO)

otteniamo il testo:
... PROC DATA=DATI.INGRESSO; RUN;

La sintassi risulta corretta per il linguaggio macro, ma non per il sistema SAS che segnaler errore in quanto nella dichiarazione PROC non presente il nome della procedura da eseguire. Nell'esempio che segue sono stati sostituiti i parametri posizionali da quelli con parola chiave. Usando le parole chiave possiamo indicare i valori (detti di default) che debbono essere assunti da quei parametri che non vengono citati nel richiamo della macro:
%MACRO M1 (P=PRINT, SDS=WORK.DATA1); PROC &P DATA=&SDS; RUN; %MEND M1; ... %M1 (SDS=DATIMIEI.INGRESSO)

Il valore del parametro P non stato specificato al momento del richiamo e quindi viene preso quello assegnato nella macroistruzione %MACRO. Il secondo valore stato specificato e verr quindi considerato come valore attuale del parametro SDS. In questo caso si ottiene:
PROC PRINT DATA=DATIMIEI.INGRESSO; RUN;

Il prossimo esempio richiama una macro facendo uso sia di parametri a parola chiave che posizionali. Nel richiamo stato specificato un solo valore ("DATIMIEI.INGRESSO") che verr assegnato al primo parametro (SDS), che posizionale. Non specificato il valore da assegnare al secondo parametro che essendo a parola chiave, assumer, come nel caso precedente, il valore previsto nella macro-istruzione %MACRO.
%MACRO M1 ( SDS,P=PRINT); PROC &P DATA=&SDS; RUN; %MEND M1; ... %M1 (DATIMIEI.INGRESSO) ...

304

Si noti che il parametro posizionale precede quello con parola chiave. Il valore del parametro P non stato indicato nel richiamo per cui vale quello specificato in fase di definizione della macro M1 ("PRINT"). Si ottiene cos:
PROC PRINT DATA=DATIMIEI.INGRESSO; RUN;

8.7.

Macro-variabili locali e globali

Le macro-variabili definite dentro una macro si chiamano locali e quelle definite fuori si chiamano globali. Le macro-variabili globali sono utilizzabili sia all'esterno che all'interno delle macro, mentre quelle locali sono utilizzabili solo all'interno della macro nella quale sono state definite. I parametri di una macro sono sempre macro-variabili locali. Esempio:
%MACRO M1 (SDS, P=PRINT); PROC &P DATA=&SDS; RUN; %LET X=&Y; %MEND M1; ... %LET Y=ESEMPIO; %M1 (DATIMIEI.INGRESSO) %LET B=&X; ...

La macro-istruzione %LET, che si trova all'interno della macro, assegna il valore "ESEMPIO" (contenuto di Y, macro-variabile globale) alla macro-variabile X (locale). La macro-istruzione %LET che si trova dopo la chiamata della macro, provoca un messaggio di errore in quanto non esiste una macro-variabile X globale e provoca l'assegnazione del valore "&X" alla macro-variabile B (globale). possibile forzare l'utilizzo di macro-variabili locali e globali con le macro-istruzioni %LOCAL e %GLOBAL. Esempio:
%MACRO A; %LOCAL X; %LET X=1; %MEND A; %MACRO B; %GLOBAL Y; %LET Y=2; %MEND B;

La macro A definisce la macro-variabile X locale: pu essere cio utilizzata solo all'interno della macro A. La macro B definisce la 305

macro-variabile Y globale: pu essere utilizzata sia all'interno che all'esterno della macro B. Macro-variabili locali e globali non interferiscono tra loro anche se hanno lo stesso nome:
%MACRO A; %LOCAL X; %LET X=123; %MEND A; ... %LET X=ABC; %A /* richiama la macro A */ %LET Y=&X;

L'ultima macro-istruzione %LET assegna ad Y il valore "ABC" che il valore che assume la macro-variabile globale X; infatti, l'assegnazione della macro-variabile locale X, fatta all'interno della macro A, non muta il valore della macro-variabile globale omonima. I nomi delle macro-variabili insieme ai loro contenuti vengono memorizzati in speciali tabelle di nome "Symbol Table". All'apertura di una sessione SAS (o all'inizio di un job batch) viene creata la Symbol Table globale (cos chiamata perch contiene le macro-variabili globali). All'inizio dell'esecuzione di una macro viene creata la Symbol Table locale relativa a quella macro. Quando all'interno di una macro si incontra un riferimento ad un'altra macro, viene creata una seconda Symbol Table locale relativa a questa ultima, ecc. ecc.. Se dall'interno di una macro si referenzia una macro-variabile, affinch l'analizzatore macro possa risolvere il riferimento (cio sostituirlo con la stringa che rappresenta il valore della macrovariabile), viene avviata una ricerca a cominciare dalla Symbol Table locale relativa alla macro nella quale si trova il riferimento. Se la ricerca fallisce, si prosegue consultando la Symbol Table della macro chiamante (se ce ne una) e cos via, a ritroso, fino ad arrivare alla Symbol Table globale. Qualora non esista alcuna entrata avente nome uguale a quello cercato, verr generato un messaggio di errore. Se invece esiste, si prende il valore della macro-variabile trovata (in questo caso si dice che il riferimento stato risolto). Se all'interno di una macro si definisce una macro-variabile, affinch si possa effettuare l'assegnazione, l'analizzatore di macro interroga la Symbol Table locale per verificare se c' gi un'entrata avente lo stesso nome. Se la ricerca si conclude positivamente, all'interno della Symbol Table locale viene effettuata una nuova assegnazione della macro-variabile (cio ne viene sostituito il valore). Se invece l'esito della ricerca negativo, si prosegue consultando la Symbol Table della macro chiamante (se ce ne una) e cos via, a ritroso, fino ad arrivare alla Symbol Table globale. Qualora durante la scansione delle varie Symbol Table viene trovata 306

una macro-variabile avente quel nome, la definizione viene effettata nella Symbol Table ove la ricerca ha dato esito positivo. Se invece la macro-variabile non mai stata definita in precedenza, allora essa viene definita nella Symbol Table locale pi "interna", cio quella che contiene la definizione. Il programma riportato di seguito mostra un esempio di richiamo di macro dall'interno di altre macro. Vengono usate le macrovariabili &T, &T1, &T2 e &T3 (appartenenti a diverse Symbol Table come mostrato in figura 8.9) sia prima che dopo la loro definizione. Il sistema segnaler con messaggi di errore gli usi non corretti.
%MACRO UNO; %LET T1=UNO; %PUT 1) &T &T1 &T2 &T3; %DUE %PUT 1) (dopo DUE) &T &T1 &T2 &T3; %MEND UNO; %MACRO DUE; %LET T2=DUE; %PUT 2) &T &T1 &T2 &T3; %TRE %PUT 2) (dopo TRE) &T &T1 &T2 &T3; %MEND DUE; %MACRO TRE; %LET T3=TRE; %PUT 3) &T &T1 &T2 &T3; %MEND TRE; ... %LET T=Eseguo la macro; %UNO RUN; ...

Le Symbol Table prodotte quando ci si trova nella macro TRE sono schematizzate in figura 8.9. La Symbol Table di livello 1 viene creata quando si entra nella macro UNO e viene cancellata quando si esce. Analogamente avviene per la Symbol Table di livello 2, che viene creata all'entrata della macro DUE e viene cancellata all'uscita, e per quella di livello 3 che dipende dalla macro TRE. La Symbol Table di livello 0 o globale viene creata a inizio sessione e quindi raggiungibile da qualsiasi punto del programma SAS. La stampa che viene prodotta dal frammento di programma sopra riportato :
1) Eseguo la macro UNO &T2 &T3 1301: COLUMN 16 1301: COLUMN 20 WARNING 1301: APPARENT SYMBOLIC REFERENCE NOT RESOLVED 2) Eseguo la macro UNO DUE &T3 1301: COLUMN 20 WARNING 1301: APPARENT SYMBOLIC REFERENCE NOT RESOLVED 3) Eseguo la macro UNO DUE TRE 2) (dopo TRE) Eseguo la macro UNO DUE &T3 1301: COLUMN 31 WARNING 1301: APPARENT SYMBOLIC REFERENCE NOT RESOLVED 1) (dopo DUE) Eseguo la macro UNO &T2 &T3 1301: COLUMN 27

307

1301: COLUMN 31 WARNING 1301: APPARENT SYMBOLIC REFERENCE NOT RESOLVED

Symbol Table: livello 0


SYSDATE=... SYSDAY=... ......... T=Eseguo la macro

Symbol Table: livello 1


T1=UNO

Symbol Table: livello 2


T2=DUE

Symbol Table: livello 3


T3=TRE

Figura 8.9: Symbol Tables Nel linguaggio macro sono previste diverse istruzioni di programmazione. Molte di esse hanno lo stesso nome delle equivalenti dichiarazioni SAS di cui mantengono la sintassi e il modo di funzionare (per quanto possibile tenendo conto della diversit del linguaggio!). Alcune macro-istruzioni possono essere utilizzate solo all'interno di macro, altre solo all'esterno, altre ancora possono essere utilizzate indifferentemente all'interno o all'esterno. Segue l'elenco delle macro-istruzioni valide sia all'interno che all'esterno di macro: %CMS %GLOBAL %INPUT %LET %MACRO %PUT %TSO per eseguire comandi di CP/CMS da un pro- gramma SAS per forzare l'uso della symbol table di livello 0 per leggere macro-variabili (in conversazionale o in DMS) per definire macro-variabili per iniziare la definizione di una macro per scrivere un testo per eseguire comandi di TSO da un programma SAS. 308

Macro istruzioni valide solo all'interno di macro: %* ....; %DO-%END %DO-%END iterativo %DO-%UNTIL %END %DO-%WHILE %END %GOTO label %label: per inserire commenti per definire un blocco di macro-istruzioni per eseguire iterativamente un blocco di macroistruzioni per eseguire iterativamente un blocco di macroistruzioni per eseguire iterativamente un blocco di macroistruzioni per saltare incondizionatamente ad altre macro-istruzioni per indicare un punto ove saltare

%IF-%THEN-%ELSE per condizionare l'esecuzione di macroistruzioni %LOCAL %MEND per forzare l'utilizzo della Symbol Table locale per terminare la definizione di una macro.

8.8. Descrizione delle principali macroistruzioni


La macro-istruzione %INPUT permette di ricevere dati direttamente dall'utente in modo conversazionale. La sintassi : %INPUT [<macro-variabile 1>] [<macro-variabile 2>] ...; Se non si specificano i nomi delle macro-variabili, la stringa di caratteri fornita in ingresso verr assegnata alla macro-variabile automatica SYSBUFFR. Se invece si specificano i nomi di n macrovariabili, verranno assegnate le prime n stringhe fornite in ingresso alle n macro-variabili specificate, considerando lo spazio come separatore. Ci che rimane verr assegnato alla macro-variabile automatica SYSBUFFR. La macro-istruzione %IF-%THEN-%ELSE permette di condizionare altre macro-istruzioni o testi costanti. La sintassi : 309

%IF <condizione> %THEN <macro-istruzione>; %ELSE <macro-istruzione>; dove: condizione una espressione condizionale scritta con regole del tutto simili a quelle usate nella dichiarazione IF del linguaggio SAS;

macro-istruzione una macro-istruzione o una parte di testo. Esempi:


%IF &A<3 %THEN %PUT il valore va bene; %ELSE %PUT il valore non va bene; ... %IF &A= %THEN %PUT A non ha valore; ... %IF &A<3 %THEN %STR(PROC PRINT;); %ELSE %STR(PROC MEANS;); ... %IF &A=99 %THEN ENDSAS;

La macro-istruzione %DO iterativa permette di ripetere l'esecuzione di altre macro-istruzioni o testi costanti. La sintassi la seguente: %DO indice=inizio %TO fine %BY passo; ....... %END; Esempio:
%DO I=1 %TO 10; PROC PRINT DATA=DATI&I; %END; %DO I=1 %TO 10; %PUT Ciclo &I; %END;

8.9.

Richiamo di macro stile istruzione

Facendo uso delle opzioni previste dalla sintassi delle macroistruzioni possibile definire macro che possono essere richiamate usando lo stesso stile con il quale si richiamano dichiarazioni SAS. Per essere abilitati a questo tipo di chiamata occorre: 310

specificare la opzione IMPLMAC in una dichiarazione OPTIONS; specificare la %MACRO. Esempio:


OPTIONS IMPLMAC DQUOTE; %MACRO A (X, Y)/STMT; %PUT Parametri passati: X=&X e Y=&Y; %MEND A;

opzione

STMT

nella

macro-istruzione

La macro A pu essere richiamata con lo stile usuale, o stile "nome". Esempio:


%A (UNO, DUE)

oppure pu essere richiamata con lo stile "istruzione". Esempio:


A UNO DUE;

Il richiamo a macro con lo stile nome, ha regole diverse rispetto a quello con lo stile istruzione. Segnaliamo di seguito tali differenze: si omette il carattere "%" dal nome; si omettono le parentesi che racchiudono i parametri (eventuali); si separano i parametri con spazi anzich con virgole; si mette un carattere ";" alla fine della chiamata; si deve inserire la chiamata tra due dichiarazioni SAS (e non in mezzo ad una dichiarazione); si abilita la chiamata con le opzioni IMPLMAC (nella dichiarazione OPTIONS) e STMT (nella macro-istruzione %MACRO). Scriviamo ad esempio una macro che parametrizza la chiamata alla PROC MEANS:
OPTIONS IMPLMAC; %MACRO MEDIE (OSSERV,DECIMALI=3) / STMT; PROC MEANS MAXDEC=&DECIMALI %IF &OSSERV = %THEN DATA=_LAST_(OBS=&OSSERV); ;RUN; %MEND MEDIE;

Essa pu essere richiamata con lo stile istruzione in uno dei seguenti modi:
MEDIE; MEDIE 25; MEDIE 25 DECIMALI=5; /* non viene passato alcun parametro */ /* viene passato 1 parametro */

/* vengono passati 2 parametri */

311

Gli sviluppi relativi alle chiamate precedenti sono:


PROC MEANS MAXDEC=3; RUN; PROC MEANS MAXDEC=3 DATA=_LAST_(OBS=25); RUN; PROC MEANS MAXDEC=5 DATA=_LAST_(OBS=25); RUN;

Scriviamo ora una macro di nome PROC (non rientra fra le parole riservate di figura 8.8) da richiamare con lo stile istruzione:
OPTIONS IMPLMAC; %MACRO PROC (P1,P2,P3,P4,P5,P6,P7,P8) / STMT; %LET PR=PRINT,MEANS,PLOT,CHART; %IF %INDEX(%QUOTE(&PR),%UPCASE(&P1))=0 %THEN %PUT Non hai il permesso di usare la proc &P1; %ELSE %STR(PROCEDURE &P1 &P2 ... &P8;); %MEND PROC;

E' interessante determinare cosa succede se si esegue il seguente programma SAS:


PROC FSEDIT; PROCEDURE FSEDIT; PROC PRINT; RUN;

La prima riga richiama la macro PROC che produrr il messaggio specificato nella %PUT, che ci avverte che non possiamo utilizzare la procedura FSEDIT. Infatti la macro-funzione %INDEX restituisce il valore 0 in quanto non esiste la sottostringa "FSEDIT" (parametro posizionale della macro) nella stringa contenuta nella macrovariabile &PR. La %IF che segue perci sceglier di inviarci il messaggio piuttosto che eseguire la procedura. La seconda riga non interferisce con la macro definita: il nome della macro PROC e non PROCEDURE. Verr quindi eseguita normalmente la procedura FSEDIT. La terza riga richiama la macro. Poich la parola PRINT (parametro della macro) si trova come sottostringa nella stringa contenuta dalla macro-variabile &PR, la macro-funzione %INDEX restituisce il valore 1 (posizione del primo carattere della sottostringa cercata). La macro-istruzione %IF che segue sceglier la via %ELSE che prevede il richiamo della procedura avente il nome uguale al parametro passato alla macro. Lo sviluppo relativo alla chiamata il seguente:
PROCEDURE PRINT;

312

8.10.

Macro richiamabili come comandi

Si possono richiamare le macro da una riga Command del DMS usando lo stesso stile dei comandi DMS se si specifica l'opzione CMD nella macro-istruzione %MACRO e si usa l'opzione CMDMAC nella dichiarazione OPTIONS. Le macro definite con lo stile comando possono essere chiamate con le normali convenzioni dello stile istruzione e devono produrre comandi validi per le righe Command del DMS. Tutte le altre convenzioni delle macro restano invariate. Per richiamare una macro con lo stile comando occorre: portare il cursore in una riga comando di qualsiasi finestra; inserire l'opzione CMD nella macro-istruzione %MACRO; non usare il simbolo "%" (percento) nel nome della macro; non mettere la lista dei parametri tra parentesi; separare i parametri con uno spazio; usare il punto e virgola dopo il richiamo della macro solo se segue nella stessa riga un altro richiamo di macro o comando DMS. Sono elencati di seguito alcuni comandi DMS che possono essere utilizzati nelle macro stile comando: LOG sposta il cursore sulla riga Command della finestra LOG rendendo attiva la finestra; PROGRAM sposta il cursore sulla riga Command della finestra PROGRAM rendendo attiva la finestra; OUTPUT sposta il cursore sulla riga Command della finestra OUTPUT rendendo attiva la finestra; CURSOR <n> sposta il cursore alla riga n-esima; SPLIT sposta la riga di divisione delle finestre LOG e PROGRAM alla riga dove si trova il cursore; INCLUDE <nome> inserisce il programma referenziato da nome nella finestra PROGRAM. Segue un esempio che utilizza i comandi elencati in precedenza per creare una macro, richiamabile da riga Command, che rende pi facile lavorare in ambiente DMS. Tale macro potrebbe anche essere associata ad un tasto PFK anche se non esplicitamente mostrato nell'esempio:

313

OPTIONS CMDMAC; %MACRO INCLUDI / CMD; LOG; CURSOR 5; SPLIT; PROGRAM; INCLUDE &PROG; MEND INCLUDI;

Questa macro verr richiamata specificando sulla riga Command di qualsiasi finestra:
INCLUDI MIOPROG

il programma di nome MIOPROG apparir nella finestra PROGRAM dopo che tale finestra stata allargata. Segue un altro esempio che crea una macro di nome STAMPA, richiamabile dalla riga Command della finestra di PROGRAM.
OPTIONS CMDMAC DQUOTE; %MACRO STAMPA (OSSERV) / CMD; PROGRAM; %IF &OSSERV= %THEN %LET P=%STR(PROC PRINT; RUN;); %ELSE %LET P=%STR(PROC PRINT DATA=_LAST_(OBS=&OSSERV); RUN;); SUBMIT "&P"; %MEND STAMPA;

Esaminiamo come verr sviluppata la macro STAMPA se si usano le seguenti chiamate:


STAMPA 5 STAMPA

La prima richiama la macro STAMPA passandogli come parametro il valore 5; la macro si sviluppa nel seguente modo:
SUBMIT "PROC PRINT DATA=_LAST_(OBS=5); RUN;"

Nel secondo caso, trovando un parametro vuoto, lo sviluppo sar:


SUBMIT "PROC PRINT; RUN;"

Nelle macro tipo comando risultano particolarmente utili le macrovariabili gestite dal DMS. Riportiamo di seguito le pi importanti, gi viste nel paragrafo 8.3: 314

DMSMSGID numero dell'ultimo messaggio fornito dal DMS; DMSWID finestra del DMS attiva attualmente (L=LOG; O=OUTPUT; P=PROGRAM; );

DMSLMSG testo del messaggio corrente (che appare sotto la riga DMSPMSG di Command) relativo rispettivamente alla finestra di DMSOMSG LOG, di PROGRAM o di OUTPUT; DMSLFK1 ... contengono rispettivamente i valori correnti dei tasti funzioDMSLFK24 nali PFK1-PFK24 relativi alla finestra LOG; DMSPFK1 ... contengono rispettivamente i valori correnti dei tasti funzioDMSPFK24 nali PFK1-PFK24 relativi alla finestra PROGRAM; DMSOFK1 ... contengono rispettivamente i valori correnti dei tasti funzioDMSOFK24 nali PFK1-PFK24 relativi alla finestra OUTPUT; Vediamo come esempio una macro di nome RIPROVO, richiamabile dalla finestra LOG o PROGRAM. Scrivendo RIPROVO sulla riga di comando della finestra PROGRAM si otterr l'ampliamento della finestra LOG e successivamente l'esecuzione del programma presente nella finestra PROGRAM in quel momento. Viceversa, se siamo nella finestra LOG ed inviamo il comando RIPROVO sulla riga di comando, verr ampliata la finestra PROGRAM e sar richiamato l'ultimo programma SAS mandato in esecuzione.
OPTIONS CMDMAC DQUOTE; %MACRO RIPROVO / CMD; %IF &DMSWID=L %THEN %DO; CURSOR 2; SPLIT; PROGRAM; RECALL; %LET DMSPMSG=MODIFICA E RIESEGUI!; %END; %ELSE %DO; CURSOR 24; SPLIT; LOG; %LET DMSLMSG=ESEGUITO &SYSTIME; SUBMIT; %END; %MEND RIPROVO;

Il prossimo esempio mostra una macro di nome CAMBIO che pu essere richiamata col nome o per mezzo di una delle due PFK ad essa associate (PFK12 e PFK24). 315

Dopo il richiamo della macro, diretta o indiretta per mezzo delle PFK, otterremo lo zoom della finestra LOG se siamo su quella di PROGRAM, o di quella di PROGRAM, se siamo sulla finestra LOG.
OPTIONS CMDMAC DQUOTE; %MACRO CAMBIO / CMD; %IF &DMSWID=L %THEN %DO; CURSOR 2; SPLIT; PROGRAM; %LET DMSPMSG=FINESTRA PGM ATTIVA!; %END; %ELSE %DO; CURSOR 24; SPLIT; LOG; %LET DMSLMSG=FINESTRA LOG APERTA; %END; %MEND CAMBIO; %LET DMSLFK12=CAMBIO; %LET DMSLFK24=CAMBIO;

8.11. Definizione automatica delle macro al momento del richiamo


Il sistema SAS permette anche l'esecuzione di macro non definite o incluse direttamente nella sessione corrente (usando, ad esempio, il comando INCLUDE inviato dalla linea di comando). Infatti le macro, da utilizzare nella presente sessione, possono trovarsi su una libreria dell'utente e possono essere state definite e conservate in una precedente sessione di lavoro. Detto metodo di richiamo delle macro (definito: "autocall", presenta notevoli vantaggi ; in particolare: le macro che vengono eseguite sotto condizione verranno incluse solo se dette condizioni sono verificate (inclusione dinamica); il sistema SAS ricerca le macro automaticamente nelle librerie definite dall'utente (archivi di tipo MACLIB per il CMS o dataset partitioned per MVS/TSO), svincolandolo dall'obbligo di prevedere e richiamare le macro che verranno utilizzate successivamente; possibile utilizzare macro fornite da SAS Institute Inc. in librerie presenti nel nastro di installazione del sistema SAS; 316

possibile utilizzare pi librerie contemporaneamente; possibile richiamare, con l'opzione "autocall" macro tipo comando, istruzione o nome. Per usare il richiamo automatico delle macro occorre: definire le librerie in cui vogliamo sia fatta la ricerca mediante gli opportuni comandi del particolare sistema operativo utilizzato (segue esempio); specificare l'opzione MAUTOSOURCE all'inizio della sessione SAS o, successivemente, con la dichiarazione OPTIONS; richiamare liberamente le macro presenti nelle librerie definite. La definizione delle librerie contenenti le macro che vogliamo richiamare dinamicamente durante una sessione SAS o in un programma viene fatta all'inizio sessione utilizzando comandi propri del sistema operativo. Nel seguito sono riportati esempi di definizione di librerie di macro per alcuni sistemi operativi. A questo riguardo opportuno far presente che detti esempi sono da considerarsi come un "fac simile" di comandi da inviare e quindi non sempre vanno digitati "alla lettera"; infatti, in funzione delle versioni di sistema, operativo e SAS, usate nonch degli standard adottati dalla installazione, potrebbero presentarsi delle differenze. MVS
//JOBMIO // //SASAUTOS // JOB ... EXEC SAS,OPTIONS='MAUTOSOURCE' DD DD DSN=MACLIB.MIA ,DISP=SHR ..... ... altre DD eventuali...

TSO
SAS OPTIONS('MAUTOSOURCE') AUTOS('MACLIB.MIA')

CMS
GLOBAL MACLIB MYMACLIB SASBAUTO SASEAUTO

.......

Nome di una libreria di macro fornita dall'utente.

Nome di una libreria di macro fornita da SAS Institute Inc.. Si tenga presente che, in funzione della versione del sistema SAS e dell'installazione, esso pu variare.

317

FILEDEF SASAUTOS DISK MYMACLIB MACLIB * FILEDEF SASAUTOS DISK SASBAUTO MACLIB * ( CONCAT FILEDEF SASEAUTOS DISK SASEAUTO MACLIB * ( CONCAT ... altre FILEDEF eventuali...

VSE
// // // // // // JOB ... DLBL SASMAUT,'librerie macro SAS Institute',99/365 EXTENT ,VOLSER DLBL USERAUT,'librerie macro utente',99/365 EXTENT ,VOLSER LIBDEF SL,SEARCH=(SASMAUT,USERAUT),PARM='MAUTOSOURCE'

SAS Institute Inc. fornisce, inserendola nel supporto di installazione del prodotto, una libreria contenente alcune macro di uso sia generale ed altre relative ad alcune componenti SAS. Tra esse ve ne sono anche alcune di tipo comando. A titolo di esempio, di seguito ne elenchiamo qualcuna. %COMPRESS (argomento) elimina gli spazi multipli dall'argomento; %DATATYP (argomento) ritorna i valori NUMERIC o CHARACTER a seconda se l'argomento numerico o no; %LEFT (argomento) toglie eventuali spazi a sinistra all'argomento; %KEYPUSH (macro tipo comando) salva i valori correnti dei PFK; %KEYPOP (macro tipo comando) ripristina i valori salvati dei PFK.

318

9. Cenni di SAS/FSP

9.1.

Generalit del SAS/FSP

La componente SAS/FSP (Full Screen5 Product) del sistema SAS stata progettata per permettere di lavorare sotto la guida di menu e gestire tutte le possibilit offerte dai terminali full screen quali: colore, doppia luminosit, ecc.. Con il SAS/FSP possibile: creare nuovi archivi SAS; modificare archivi SAS esistenti; consultare archivi SAS, ricercando valori al loro interno; inserire dati in archivi SAS in modo guidato e controllato; scrivere lettere ed associarle a liste di indirizzi, personalizzarle automaticamente, ecc.; utilizzare fogli elettronici (spreadsheet), leggendo i dati da tabulare da archivi SAS o scrivendo i risultati su archivi SAS. In questo capitolo verranno illustrate solo sommariamente le principali caratteristiche del prodotto SAS/FSP senza entrare nel dettaglio delle numerose possibilit offerte per le quali rimandiamo all'apposito manuale6. Una trattazione esaustiva, anche se sintetica del prodotto, risulterebbe troppo voluminosa per un libro che si
In inglese il termine full screen (che traduciamo "schermo pieno") indica un modo di lavoro che si contrappone a quello "linea dopo linea" (line mode). In line mode il colloquio uomo-macchina avviene in modo sequenziale, linea dopo linea. In full screen mode possibile accedere qualsiasi punto dello schermo mediante un cursore che appare sul video. Non tutti i terminali possono lavorare in full screen (ad esempio, in ambiente IBM, necessario utilizzare terminali della famiglia 327X). Mediante opportuni programmi, detti emulatori, possibile far funzionare in full screen mode anche terminali tipicamente funzionanti in line mode. 2 SAS/FSP User's Guide
1

319

prefigge lo scopo di guidare ad un utilizzo appropriato delle parti basilari del sistema SAS. Saranno per indicati, attraverso esempi, gli strumenti indispensabili per un corretto utilizzo di questa componente. Le procedure della componente SAS/FSP sono: PROC FSBROWSE per visualizzare, osservazione dopo osservazione, i dati presenti negli archivi SAS; la ricerca delle osservazioni pu essere effettuata usando comandi semplici ma molto potenti; per gestire fogli elettronici; i dati possono essere prelevati da un archivio SAS e successivamente memorizzati in esso; per convertire dati, creati con vecchie versioni di SAS/FSP, in equivalenti validi per nuove versioni del prodotto; per accedere alle osservazioni di archivi SAS e permettere la ricerca e la visualizzazione di dati (questa funzione permessa anche dalla PROC FSBROWSE); inoltre possibile correggere, aggiornare ed inserire nuovi dati in archivi SAS. La procedura offre la possibilit di creare nuovi archivi SAS senza dover ricorrere alla scrittura di un apposito passo di DATA. Inoltre possibile disegnare apposite maschere (screen) per guidare le fasi di ingresso o di aggiornamento dei dati, prevedere attributi per i campi dello schermo (es.: doppia luminosit), ecc.. Usata in congiunzione con la FSLETTER, questa procedura permette la personalizzazione e la gestione di lettere od altri documenti; per gestire documenti (es.: lettere commerciali); per visualizzare archivi grezzi (sequenziali o membri di librerie); 320

PROC FSCALC

PROC FSCON

PROC FSEDIT

PROC FSLETTER PROC FSLIST

PROC FSPRINT

per visualizzare archivi SAS in modo efficiente.

Le procedure della componente SAS/FSP prevedono numerosi ambienti operativi e poich, per ciascuno di essi, prevista una associazione "comandi-tasti funzionali (PFK)" definibile anche dall'utente, nella trattazione faremo quasi sempre riferimento al comando da inviare invece che al tasto funzionale associato. Ricordiamo per che in ogni ambiente possibile chiedere la associazione "comandi-PFK" mediante il comando KEYS da inviare sulla Command line.

9.2.

Cataloghi SAS

Per sfruttare la potenzialit delle procedure sopra elencate necessario introdurre il concetto di cataloghi SAS. Essi rappresentano un diverso tipo di archivi SAS e risiedono anch'essi in librerie. I loro nomi seguono le stesse convenzioni di quelli SAS tranne che non possono essere composti da pi di sette caratteri. Ogni catalogo composto a sua volta di membri. Nei cataloghi possibile memorizzare, in qualit di membri, i seguenti oggetti: lettere e loro specifiche di stampa, usando la procedura FSLETTER; formati di schermi personalizzati (screen) usando le procedure FSBROWSE e FSEDIT; fogli elettronici, programmi sorgente, programmi compilati, specifiche e formati di stampa, usando la procedura FSCALC; altri tipi di membri che non sono richiamabili dalle procedure della componente SAS/FSP, ma che incontreremo nel presente testo quando si parler di SAS/GRAPH (cfr. capitolo 10). Analogamente a quanto fatto per gli archivi SAS, per identificare un catalogo si devono specificare: il nome della libreria di appartenenza ed il nome del catalogo stesso. Se si omette il nome della libreria viene assunta, come di consueto, la libreria WORK e il catalogo diviene temporaneo. Esempi di nomi di cataloghi: WORK.CAT LIB1.CATAL25 I membri di un catalogo vengono identificati da un nome e da un tipo. Mentre il nome del membro pu essere scelto liberamente 321

seguendo le convenzioni descritte sopra, il tipo caratterizza i dati in esso contenuti e specifica a quale procedura tale membro si riferisce. Sono elencati di seguito alcuni tipi di membri e, tra parentesi, le procedure che li gestiscono: CALC FORM LETTER SCREEN PGM EXE REPORT PARMS Fogli elettronici (FSCALC) Specifiche di stampa (FSCALC, FSLETTER) Lettere (FSLETTER, FSEDIT) Schermi personalizzati (FSEDIT, FSBROWSE) Programmi sorgenti (FSCALC) Programmi compilati (FSCALC) Formati di stampa (FSCALC) Parametri (FSCALC)

Per identificare completamente un membro, oltre al nome ed al tipo, necessario specificare il catalogo di appartenenza. Esempi di nomi di membri: WORK.CAT.MEM1.SCREEN LIB1.CATAL25.PAGHE.SCREEN I cataloghi hanno un direttorio (directory) che possiamo assimilare al descrittore di un archivio SAS. Nel direttorio infatti, sono registrate informazioni circa il catalogo, tra cui l'elenco dei membri in esso contenuti. Un catalogo pu essere creato, e successivamente visualizzato su terminale, eseguendo alternativamente le dichiarazioni seguenti: PROC FSCALC C=libreria.catalogo ; RUN; oppure: PROC FSLETTER LETTER=libreria.catalogo; RUN; Entrati in ambiente di visualizzazione del catalogo, possibile una sua gestione, scrivendo uno dei seguenti comandi nella apposita riga Command (alcuni comandi sono gi associati a PFK):

322

BACKWARD BROWSE nome.tipo COPY nome.tipo | libreria.catalogo. nome.tipo DELETE nome.tipo EDIT nome.tipo END FORWARD FREE HELP KEYS PRINT nome.tipo SEND nome.tipo E' inoltre possibile dare i seguenti comandi sulla riga in cui visualizzato il nome del membro che vogliamo selezionare: E,S,X B P R EDIT (entra in ambiente di modifica) BROWSE (entra consultazione) in ambiente di

entra in ambiente di SEND e rilascia una lettera (in FSLETTER) RENAME (modifica il nome o la descrizione).

Ricordiamo che spiegazioni dettagliate possono essere richieste codificando HELP nella riga di comando.
Directory for Catalog: MIALIB.CATMIO Command ===> edit fscalc.parms Name _ _ _ _ FSCALC CONS1 MOROSI FATTURE Type PARMS LETTER LETTER SCREEN Description PROC FSCALC PARAMETERS CIRCOLARE RICHIESTA CONSUNTIVI SOLLECITO PAGAMENTO MASCHERA IMMISS. FATTURE Updated 24JUN88 24JUN88 24JUN88 24JUN88

Figura 9.1: Visualizzazione del direttorio di un catalogo In figura 9.1 parzialmente riportata la schermata che appare quando si entra in ambiente di visualizzazione di un catalogo. In tale ambiente possibile creare nuovi membri del catalogo (con il comando edit) ed aggiornare, cancellare o rinominare membri gi esistenti. necessario tener presente per, che ogni procedura permette di aggiornare solo i membri di propria pertinenza; 323

non , ad esempio, permesso aggiornare lettere se siamo arrivati in questo ambiente con la procedura FSCALC, come non permesso aggiornare membri di tipo CALC se si arrivati attraverso la FSLETTER. I prossimi paragrafi chiariranno ulteriormente l'uso dei cataloghi con le procedure del sistema SAS/FSP.

9.3.

La procedura FSEDIT

Con la procedura FSEDIT possibile: creare archivi SAS; aggiungere osservazioni ad archivi SAS; ricercare osservazioni in archivi SAS secondo determinati criteri; modificare osservazioni in archivi SAS; definire o modificare le maschere-video di presentazione delle osservazioni di un archivio SAS; definire i controlli da effettuare sui valori letti in ingresso o, come si dice in gergo, effettuare una fase di data entry validando direttamente i dati all'atto della loro sottomissione.

9.3.1. Creazione di un archivio SAS


Per creare un archivio SAS con la procedura FSEDIT, la si deve richiamare usando alternativamente le dichiarazioni seguenti: PROC FSEDIT NEW= <archivio_SAS> ; RUN; oppure: PROC FSEDIT NEW= <archivio_SAS> [SCREEN=libreria.catalogo.membro ] ; RUN; dove: creare; e <archivio_SAS> indica il nome del nuovo file da libreria.catalogo.membro indica un membro di tipo SCREEN che pu essere utilizzato dalla procedura per memorizzare la maschera-video usata durante le fasi di data entry, personalizzata dall'utente (non necessario specificare il tipo del membro che obbligatoriamente "SCREEN"). 324

Quando si creano nuovi archivi con la procedura FSEDIT,

inizialmente, viene presentato un pannello simile a quello mostrato in figura 9.2.

FSEDIT Data Set Definition for WORK.ANAGRAFE Command ===> Name titolo__ nome____ cognome_ cap_____ citta___ ________ ________ ________ Type $ $ $ _ $ _ _ _ Length 5__ 15_ 20_ ___ 20_ ___ ___ ___ Label Titolo professionale____________________ Nome del professionista_________________ ________________________________________ Codice di avviamento postale____________ Citta'__________________________________ ________________________________________ ________________________________________ ________________________________________ Format $5.___________ ______________ ______________ ______________ ______________ ______________ ______________ ______________

Figura 9.2: Creazione di un archivio SAS - definizione delle variabili Ciascuna riga del video associata ad una variabile; possibile, per ogni variabile, fornire: il nome, il tipo, la lunghezza, l'eventuale etichetta, il formato di uscita e quello di ingresso. Quest'ultimo campo non mostrato sullo schermo e per farlo apparire occorre inviare il comando RIGHT nella riga di Command. Per terminare la fase di definizione delle variabili dell'archivio, occorre digitare il comando END (o premere il PFK3). A questo punto, verr presentata una schermata simile a quella mostrata in figura 9.3. Affinch si possano inserire dati, occorre digitare il comando ADD nella riga Command.
Edit SAS data set: WORK.ANAGRAFE Screen Command ===> add Obs Warning: No observations on data set. Press END to exit or ADD to add. 1 0

TITOLO: NOME:

_____ _______________

COGNOME: ____________________ CAP: CITTA: ____________ ____________________

Figura 9.3: Creazione di un archivio SAS - inserimento di dati

325

9.3.2. Aggiornamento di un archivio SAS


Se si desidera consultare od aggiornare un archivio gi esistente, si pu richiamare la procedura FSEDIT7 in uno dei seguenti modi: PROC FSEDIT [ DATA= <archivio_SAS> ] ; RUN; oppure: PROC RUN; dove: <archivio_SAS> indica il nome di un archivio SAS esistente, da visualizzare, variare, o al quale si vogliono aggiungere osservazioni; libreria.catalogo.membro indica un membro di tipo SCREEN che pu essere utilizzato dalla procedura, contenente le personalizzazioni della mascheravideo da usare durante le fasi di data entry (non necessario specificare il tipo del membro che obbligatoriamente "SCREEN"). FSEDIT [ DATA= <archivio_SAS>] [ SCREEN=libreria.catalogo.membro ] ;

Se l'opzione DATA= non indicata vuol dire che si intende visualizzare l'ultimo archivio creato nella sessione in corso. All'inizio della sessione, verr presentata su video la prima osservazione dell'archivio specificato , come mostrato in figura 9.4.
Edit SAS data set: WORK.ANAGRAFE Command ===> Screen Obs 1 1

TITOLO: NOME:

Arch. Renzo

COGNOME: Beltrame CAP: CITTA: PISA 56100

Figura 9.4: Aggiornamento di un archivio SAS


7

La procedura FSEDIT permette di aggiornare e visualizzare solo la parte dati di un file SAS. Per aggiornare e visualizzare il descrittore di un file si pu usare la procedura del SAS/Base (anche essa interattiva e "full screen"): PROC DATASETS DDNAME= libreria ; RUN;

326

Se le variabili della osservazione sono molte e non rientrano tutte nello schermo, per visualizzare quelle che non compaiono, occorre digitare il comando RIGHT, nell'apposita riga Command. possibile a questo punto modificare il valore di qualsiasi variabile mostrata nello schermo semplicemente spostandosi sul relativo campo tramite gli appositi tasti "freccia". Quando vogliamo visualizzare un'altra osservazione possiamo usare i comandi BACKWARD e FORWARD, che ci fanno passare rispettivamente alla osservazione precedente o a quella seguente; alternativamente si pu puntare direttamente ad una osservazione digitando il suo numero sulla riga Command. Per aggiungere eventuali osservazioni in coda all'archivio, si pu dare il comando ADD (viene visualizzata una nuova osservazione con tutti i campi in bianco) o DUP (viene visualizzata una nuova osservazione con i valori delle variabili identici a quelli della osservazione precedente). Non vengono descritte in questo paragrafo le operazioni necessarie per ricercare osservazioni in quanto esse sono del tutto uguali a quelle descritte per la procedura FSBROWSE alla quale rimandiamo per maggior dettaglio.

9.3.3. Definizione e modifica di maschere-video


La procedura FSEDIT ci permette anche di definire il modo con cui le osservazioni devono essere visualizzate nonch gli eventuali controlli che devono essere effettuati sui valori digitati da terminale. Immaginiamo di aver creato un archivio ed esserci portati in ambiente di visualizzazione delle osservazioni; in mancanza di nostre indicazioni, i dati sono presentati in maniera standard sullo schermo. Possiamo per decidere di definire una maschera-video personalizzata, da usarsi per la presentazione dei dati; oppure possiamo inserire alcuni controlli da effettuare sul contenuto delle variabili in ingresso, quali indicare valori limite (massimo e minimo), oppure specificare se un determinato valore deve sempre essere inserito, ecc. In tal caso occorre digitare il comando MOD (MODify) sulla riga Command.

327

FSEDIT Screen Modification Menu Select Option ===> 1 2 3 4 5 Information about screen modification Screen Modification Field Identification Field Attributes Parameter Modification

Figura 9.5: Menu di personalizzazione La figura 9.5 mostra il menu che appare in risposta al comando MOD; si deve ora scegliere il tipo di operazione che si intende effettuare. Sono previste cinque scelte, una per richiedere informazioni sulla fase di "Screen Modification" (Help in linea) e le altre operative che ci permettono di entrare in ambiente di modifica (di parametri, di schermate, ecc.). Si ricorda a questo proposito che in ogni Command line possibile richiedere con il comando HELP ulteriori informazioni circa il particolare ambiente. Si tenga infine presente che nella versione 6 del prodotto, stato introdotto un nuovo potente linguaggio, denominato SCL (Screen Control Language), che permette di controllare nei minimi dettagli la fase di data entry.

9.4.

La procedura FSBROWSE

Con questa procedura possibile ricercare e visualizzare osservazioni in archivi SAS secondo determinati criteri. La procedura FSBROWSE ha le stesse funzioni della FSEDIT per quelle operazioni che non richiedono modifiche agli archivi. Con questa procedura si ha la sicurezza che l'utente non apporter cambiamenti di nessun genere ai dati, ma potr sfruttare tutte le possibilit di visualizzazione e di ricerca delle osservazioni. Per richiamare la procedura FSBROWSE si pu usare la seguente dichiarazione: PROC FSBROWSE [ DATA= <archivio_SAS> ] [ SCREEN=libreria.catalogo.membro ] [ LETTER=libreria.catalogo ]; RUN; dove: <archivio_SAS> indica il nome di un file esistente da visualizzare, contenente almeno una osservazione. Se <archivio_SAS> omesso, viene visualizzato l'ultimo archivio SAS creato nel corso della sessione corrente; 328

libreria.catalogo.membro indica un membro di tipo SCREEN contenente le personalizzazioni della maschera-video da usare durante le fasi di visualizzazione. Se omesso viene utilizzata una maschera standard; e libreria.catalogo indica un catalogo nel quale sono memorizzate lettere create in precedenza con PROC FSLETTER.

Per scorrere le osservazioni in modo sequenziale si usano i comandi BACKWARD e FORWARD che ci fanno spostare rispettivamente alla osservazione precedente o a quella successiva. Tali comandi sono normalmente associati rispettivamente alle PFK7 (o PFK19) e PFK8 (o PFK20). Per una ricerca diretta necessario scrivere il numero dell'osservazione desiderata sulla riga comando e premere il tasto "invio" (o "return"). Se si scrive un numero di osservazione troppo grande (maggiore del numero di osservazioni presenti nell'archivio) ci viene fornita l'ultima osservazione. Molto utile risulta la ricerca per contenuto di una singola variabile, da effettuarsi con i comandi NAME e LOCATE (abbreviato L) da scrivere come di consueto sulla riga comandi. La variabile su cui si vuole effettuare la ricerca si definisce mediante il comando: NAME <nome variabile> La ricerca del contenuto si effettua poi con i comandi: L 'valore' oppure con: L: 'valore' Esempio: immaginiamo di avere un archivio SAS contenente dati anagrafici contenente le variabili TITOLO, NOME, COGNOME, CAP, CITTA, ecc.; per ricercare la prima occorrenza nel file del cognome "Rossi" sufficiente dare i seguenti comandi: NAME COGNOME L 'Rossi' con il primo comando si seleziona la variabile di ricerca e con il secondo se ne seleziona il contenuto. Per trovare la prossima occorrenza si pu dare il comando (codificato anche in una apposita PFK): REPEAT Con questo comando vengono esclusi dalla ricerca i cognomi composti (es.: "Rossi di Montelera", "Martini e Rossi"). Per comprenderli si deve dare il comando: 329

L: 'Rossi' Qualora la ricerca sul contenuto di una sola variabile non costituisca un criterio sufficiente, possibile estenderla contemporaneamente su pi variabili mediante l'uso dei comandi STRING (abbreviato STR) e SEARCH (abbreviato S). Le variabili di ricerca vengono definite inviando il comando: STR <variabile_1> <variabile_2> ..... <variabile_n> e si effettua poi la ricerca del contenuto con : S oppure: S@ <valore1> <valore2>..... <valoren> <valore1> <valore2>..... <valoren>

a seconda che la ricerca si consideri ultimata alla prima osservazione che contiene tutti i valori specificati (ricerca AND) o a quella che ne contiene almeno uno (ricerca OR). Ad esempio: per ricercare, sempre nel nostro ipotetico archivio anagrafico, la prima osservazione contenente un professore (TITOLO="Prof.") avente cognome "Rossi" (COGNOME="Rossi") abitante a Padova (CITTA="Padova"). Una volta posizionati sulla prima osservazione dell'archivio, si devono inviare i seguenti comandi: STR TITOLO COGNOME CITTA S Prof. Rossi Padova Nel caso in cui si voglia ricercare la prima osservazione relativa ad un architetto (TITOLO="Arch.") oppure di un residente a Pisa (CITTA="Pisa"), si devono inviare i seguenti comandi: STR TITOLO CITTA S@ Arch. Pisa In entrambi i casi, la ricerca pu essere estesa ad altre osservazioni con il comando REPEAT. La ricerca pu essere ulteriormente estesa a pi criteri contemporaneamente con l'uso dei comandi FIND e FIND@ (abbreviati F e F@ ). Per criterio si intende un'espressione del tipo: <variabile> <operatore> <valore valido> dove gli operatori ammessi sono: "=" "=" "<" ">" "<=" ">=". Si sceglie F se si vuole che la ricerca dia esito positivo quando tutti i criteri sono soddisfatti (AND); si sceglie, alternativamente, F@ se la ricerca si deve fermare quando almeno una condizione soddisfatta (OR). Ad esempio, se si vogliono trovare gli indirizzi dei residenti nelle province di Pisa (valore della variabile CAP uguale a 56100) 330

e Livorno (valore della variabile CAP uguale a 57100) si deve dare il comando: F CAP>=56100 CAP<58000 Se invece si cercano gli indirizzi dei residenti a Siena (valore della variabile CAP uguale a 53100) o a Pisa si dovr dare il comando: F@ CAP=53100 CAP=56100 Anche in questo caso la ricerca si fermer alla prima osservazione che soddisfa le richieste e pu essere continuata con il comando REPEAT. La procedura prevede anche la possibilit di inviare lettere commerciali preparate con la procedura FSLETTER. Se appositamente previsto, le lettere vengono personalizzate con indirizzi, nomi, date, ecc., prima di essere inviate. possibile visualizzare i nomi delle lettere contenute nel catalogo specificato nella opzione "LETTER=", al momento del richiamo della procedura, usando il comando: CATAL e con il comando: SEND <nome lettera prescelta> possibile rilasciarle, dopo aver sostituito i valori delle variabili dell'osservazione alla quale siamo posizionati, nei relativi riferimenti contenuti nella lettera. Prima dell'invio, il sistema richiede un'ultima correzione (ad esempio si pu stabilire che il numero di protocollo venga inserito in questa fase). Senza abbandonare l'ambiente di FSBROWSE si possono predisporre nuove lettere con il comando: EDIT <nome lettera> Le lettere inviate sono affidate al sistema operativo che le metter in una coda definita in base a quanto specificato nella FORM (membro di tipo FORM del catalogo, che indica le istruzioni per la stampa) associata alla lettera (ad esempio: coda di una particolare stampante di qualit).

9.5.

La procedura FSLETTER

La procedura FSLETTER permette la scrittura, modifica, cancellazione, correzione e invio di lettere. Si entra in ambiente FSLETTER richiamando la procedura stessa con la specifica del catalogo dove vogliamo archiviare le lettere o ritrovare lettere scritte precedentemente. Le dichiarazioni da inviare sono le seguenti: 331

PROC FSLETTER LETTER=libreria.catalogo; RUN; Il sistema SAS far apparire sul terminale il direttorio del catalogo da noi richiesto. La prima volta ovviamente il catalogo sar vuoto. A questo punto possiamo entrare nell'apposito ambiente per la scrittura di lettere specificando sulla riga di comando: EDIT PROVA.LETTER dove PROVA un nome scelto dall'utente e LETTER il tipo (LETTER obbligatorio per le lettere). Si entra cos in ambiente di scrittura. Un messaggio ci avverte che la lettera che ci accingiamo a scrivere non ha associata n una descrizione n un form. Possiamo fornire la descrizione, mediante il comando seguente: DES Questa una lettera di prova A questo punto, vedremo apparire nella prima riga dello schermo la descrizione fornita; essa verr anche mostrata in ambiente di visualizzazione del direttorio. In alto a destra vediamo che accanto alla parola form ci sono dei punti interrogativi. Non abbiamo ancora specificato il form (istruzioni per l'inoltro della lettera o per la stampa) da associare alla lettera. Ignoriamo per ora questa richiesta e preoccupiamoci di inserire il testo della lettera. Con i comandi FORWARD e BACKWARD (o con i PFK7 e PFK8 associati a questi comandi) possiamo far scorrere la lettera in avanti o indietro. Finita la battitura del testo, prima di uscire da questo ambiente, possiamo definire il nome del form da associare alla lettera. Nel seguito ci preoccuperemo di compilare appropriatamente anche questa parte. Il form definito potr poi essere utilizzato per pi di una lettera. Si specifica il nome del form scrivendo nella riga Command : FORM formmio dove FORM la parola chiave e "formmio" un nome scelto dall'utente. Possiamo uscire a questo punto dalla lettera e tornare al pannello di partenza dando il comando END nella riga Command o con l'uso del PFK3. Il nostro catalogo contiene ora un elemento: la lettera PROVA completa di descrizione. Prima di poterla spedire per dobbiamo ricordarci che il form associato alla lettera non stato definito. Possiamo crearlo con il comando: EDIT formmio.FORM dove "formmio" rappresenta il nome del form che abbiamo specificato nella lettera e FORM il tipo obbligatorio. Ci viene a questo punto proposto di scegliere la stampante che useremo per scrivere 332

la lettera. Se non abbiamo una stampante laser del tipo proposto possibile scegliere pi genericamente la "Line Printer". La scelta avviene ponendo un carattere "x" nel campo che rappresenta il particolare tipo di stampante desiderata. Anche per il form possiamo fornire una breve descrizione che dobbiamo scrivere nel campo indicato da "Form Description". Continueremo a riempire quei campi che ci interessano ricordando che, una volta finiti i campi di una schermata, possiamo passare alla successiva premendo il PFK3. Una volta riempito il form e tornati al pannello del direttorio siamo pronti per l'invio della lettera; questo avverr se inviamo il comando: SEND PROVA Il sistema SAS ci riporta a questo punto in ambiente di correzione della lettera per apportare le ultime variazioni, prima dell'invio alla stampante che verr fatto automaticamente appena segnaliamo che la fase di correzione terminata, inviando il comando END (o premendo il PFK3).

9.5.1. Personalizzazione ed invio delle lettere con la PROC FSEDIT


Nella fase di scrittura della lettera possono essere lasciati in bianco alcuni campi che, successivamente in fase finale, potranno essere personalizzati. Altri campi possono essere indicati di tipo variabile. A tale scopo si devono indicare i nome delle variabili, preceduti dal simbolo "&"; esse dovranno essere contenute in un archivio SAS dal quale successivamente verranno prelevati i valori e sostituiti nel corpo della lettera. Riprendiamo l'esempio di archivio SAS NOME, COGNOME, CAP, CITTA, opportunamente nella lettera per definire lettera potrebbe ad esempio avere il nome come mostrato in figura 9.6. contenente le variabili ecc. e inseriamole i campi variabili. La PROVA e cominciare

La data e il numero di protocollo sono stati intenzionalmente lasciati in bianco per permettere il loro inserimento all'ultimo momento. I nomi preceduti dal carattere "&" rappresentano le variabili che si trovano nell'archivio anagrafico preso in considerazione. I caratteri di sottolineatura che seguono i nomi di variabili indicano al sistema SAS che il contenuto delle variabili potrebbe essere pi lungo del nome stesso della variabile e che vogliamo riservare tale spazio per il campo variabile.

333

Pisa, Prot. &nome____ &cognome &via_______________ &cap_ &citta_________

Caro &nome____ , ti scrivo per annunciarti che spero di venire presto a trovarti a &citta_________ ... Figura 9.6: Inizio di lettera al momento della scrittura Per spedire la lettera cos preparata si potr usare la procedura FSEDIT al posto della FSLETTER che in questo caso servita solo per scrivere la lettera. Con la procedura FSEDIT si richiama l'archivio anagrafico che contiene le variabili usate nella lettera e si indica il catalogo che contiene la lettera che si intende spedire. Le dichiarazioni necessarie per il richiamo della procedura sono: PROC FSEDIT DATA= <archivio anagrafico SAS> LETTER=libreria.catalogo; RUN; Occorre ora posizionarsi all'osservazione contenente i dati del destinatario (es.: Gino Bianchi di Pisa) ed infine scrivere sulla riga Command : SEND PROVA Esattamente come avviene nella PROC FSLETTER, la lettera viene messa a disposizione per le correzioni finali. A questo punto per i campi variabili risulteranno modificati con i valori della osservazione attuale dell'archivio anagrafico. Potremo cos completare la lettera, mostrata in figura 9.7, con la data e il numero di protocollo ed inviarla con il comando END. Pisa, Prot. Gino Bianchi Via Giovannoni, 32 56127 PISA Caro Gino , ti scrivo per annunciarti che spero di venire presto a trovarti a Pisa ... Figura 9.7: Frammento di lettera dopo la impaginazione automatica 334

9.6.

La procedura FSCALC

In questo paragrafo prenderemo in considerazione i fogli elettronici (in inglese, spreadsheet). Alcune volte si usa anche il termine tabelle elettroniche. In figura 9.8 riportato un esempio di tabella di tipo amministrativo che spesso si ritrova nel lavoro quotidiano.

Sviluppo Stampa Carta Filtro Lampade

PREZZO PEZZI COSTO IVA TOTALE 3000 10 30000 18 35400 350 95 33250 18 39235 10000 4 40000 18 47200 8000 3 24000 18 28320 40000 2 80000 18 94400

Figura 9.8: Frammento di una comune tabella Nelle tabelle di uso comune normalmente possiamo distinguere le caselle in due tipi: quelle (che chiameremo di input) che contengono i dati provenienti da altri documenti e quelle (che chiameremo derivate) che contengono i risultati di operazioni (somme, percentuali, ecc.) effettuate sui dati contenuti nelle caselle di input. Il primo vantaggio offerto dai fogli elettronici consiste nella possibilit di poter scrivere un programma che calcoli automaticamente le caselle derivate, evitando all'utilizzatore molto lavoro manuale ed il rischio di commettere banali errori. inoltre possibile pensare di programmare anche quelle caselle di input destinate a ricevere dati contenuti in archivi SAS. Caselle di input di questo tipo possono essere a loro volta considerate "derivate" da altri archivi. Una volta impostate le nostre tabelle risulter molto facile produrre una serie di documenti impeccabili da allegare ai nostri rapporti. I fogli elettronici gestiti dal SAS/FSP possono essere curati anche per quanto riguarda la presentazione su video o la stampa su carta, affinch anche persone non esperte di informatica, li possano gestire in modo disinvolto.

Per dare una prima idea delle possibilit di gestione delle tabelle da parte del SAS/FSP ci limiteremo a presentare un semplice 335

esempio in cui viene impostata una tabella, senza addentrarci nelle numerose specifiche particolari che possono essere date in questi casi. Facciamo per presente che il sistema molto pi completo e potente di quanto possa apparire da questa presentazione che ha carattere solo introduttivo. I fogli elettronici si gestiscono con la procedura FSCALC che dovr essere richiamata specificando: PROC FSCALC C=libreria.catalogo ; RUN; Come riportato nel paragrafo 9.2, questi comandi ci permettono di entrare in ambiente elaborazione di un catalogo. Per prima cosa dobbiamo stabilire i parametri generali relativi alle tabelle elettroniche che vogliamo costruire. Detti parametri vanno specificati solo la prima volta che utilizziamo un catalogo per le tabelle. Specificheremo cos nella riga di Command: EDIT FSCALC.PARMS Verr mostrata a questo punto una schermata di parametri che stabiliscono le azioni che il sistema dovr intraprendere nell'utilizzo delle tabelle in mancanza di indicazioni contrarie (cfr. figura 9.9). I parametri sono visualizzati in un pannello pi grande del video; sar perci necessario usare il comando FORWARD per poter vedere tutti i campi previsti dal pannello (cfr. figura 9.10). Per permettere la prosecuzione di questo esempio occorre fornire i parametri per il foglio da creare; essi si trovano elencati sotto la dicitura: "Cell characteristics for a NEW spreadsheet:", che costituisce l'ultimo gruppo di parametri del pannello di figura 9.10. Dovremo indicare "f" (FUNCTION) nel campo identificato "Cell type" e "n" (NUMERIC) nel campo identificato "Data type".

336

FSCALC parameter screen Command ===> Notes: Use scroll keys (commands) to review and/or change default values. Mapsize: 512 Row Names> Color: R Column Names> Color: C Column Width: 8 Print Command Information: <- (WARNING: Read manual before modifying) Attr: ______________ Attr: U Column spacing: 2 Form Name: ________ Prefix: ROW Prefix: COL

Fileref: ________

Use the fields below to set default characteristics for numeric cells, character cells and default cells for new spreadsheets. Default Numeric cell characteristics: Cell type: DATA Color: Y just:_________ Data type: NUMERIC Attr: ____________ Caps: N Format: BEST Dec: 0 Pattern: N Informat: F Dec: 0 Default Character cell characteristics:

Round: N Hide: N Prot: N

Figura 9.9: Prima parte dei parametri di default utilizzati nella PROC FSCALC Dal pannello dei parametri si esce, come di consueto, digitando il comando END nella riga comando. Si ritorna cos al pannello del direttorio del catalogo pronti a creare la nostra tabella con i dati che ci interessano, digitando sulla riga comando: EDIT PROVA.CALC seguita naturalmente dal tasto di ritorno. Con questo comando si chiede di creare una tabella elettronica di nome "PROVA". Ci viene richiesto a questo punto di fornire i parametri particolari per questa tabella. Dobbiamo perci indicare il numero di righe e di colonne che devono comporre la nostra tabella e la dimensione delle singole celle. Riprendiamo l'esempio di figura 9.8 indicando perci che vogliamo una tabella di 5 righe, 5 colonne e con celle di ampiezza 8 posizioni. Non utilizzeremo in questo esempio gli altri parametri previsti. Si esce da quest'ultimo ambiente scrivendo END sulla riga di comando o usando l'apposito PFK come siamo abituati a fare. Ci appare a questo punto una tabella avente le righe intestate "ROW1", "ROW2", ecc. e le colonne "COL1", "COL2", ecc.; mediante l'uso dei tasti freccia ci portiamo sulle intestazioni e le modifichiamo ottenendo come risultato la figura 9.11. Ci preoccuperemo a questo punto anche di riempire le caselle di input dalle quali si svilupper tutto il resto della tabella.

337

FSCALC parameter screen Command ===> Notes: Use scroll keys (commands) to review and/or change default values. Cell type: Data type: Format: Informat: LABEL CHARACTER $CHAR $CHAR Color: Y Attr: ____________ Just: ________ Hide: N Prot: N

Caps: N Pattern: N

Cell characteristics for a NEW spreadsheet: Cell type: f Data type: n Format: BEST Informat: W Initial value: Color: Y Round: N Attr: ____________ Caps: N Dec: 0 Pattern: N Dec: 0 Just: _______ Hide: N Prot: N

END OF PANEL--------------------------------------------------------------

Figura 9.10: Seconda parte dei parametri di default utilizzati nella PROC FSCALC
PROVA.CALC Command===> edit prova.pgm define Mode PREZZO SVILUPPO STAMPA CARTA FILTRO LAMPADE 3000 350 10000 8000 40000 PEZZI 10 95 4 3 2 COSTO IVA TOTALE

Figura 9.11: Tabella in fase di definizione Vogliamo ora definire le regole che ci permetteranno di generare automaticamente il resto della tabella. A questo scopo riportiamo il cursore nella riga comando e scriviamo EDIT PROVA.PGM per richiamare un ambiente nel quale potremo scrivere dette regole sotto forma di istruzioni e formare cos un programma. Prima di premere il tasto di ritorno per, ci preoccuperemo di spostare il cursore in basso posizionandolo sotto la tabella che abbiamo iniziato a costruire. Se prima di inviare il comando dimenticassimo di posizionare il cursore, l'editore di istruzioni ricoprirebbe la nostra tabella occupando completamente lo schermo.

338

PROVA.CALC Command ===> run prova PREZZO SVILUPPO STAMPA CARTA FILTRO LAMPADE 3000 350 10000 8000 40000 PEZZI 10 95 4 3 2 COSTO IVA TOTALE Define Mode

-------------------------------- PROVA.PGM -------------------------------Command ===> text Editor col 001 079 costo=prezzo*pezzo; iva=18; totale=costo+costo*iva/100;

Figura 9.12: Tabella e programma di gestione Nella nuova sezione che appare scriviamo le istruzioni che stabiliscono come calcolare i valori delle colonne derivate da quelle di ingresso. Ad esempio, per la colonna COSTO definiamo una relazione tra le precedenti due colonne (PREZZO e PEZZI). Per la colonna IVA invece stabiliamo che tutte le caselle siano uguali ad una costante (18). Quando abbiamo finito di scrivere il programma, ci riportiamo sulla riga di comando della tabella e scriviamo (cfr. figura 9.12): RUN PROVA Da questo punto in poi la tabella passa dalla fase di definizione a quella esecutiva; noteremo che il messaggio in alto a destra passer da Define Mode a Run Mode. In quest'ultimo ambiente, il programma precedentemente digitato eseguito ogni volta che viene modificata almeno una cella di input. Pu succedere per a questo punto che non tutto vada come vorremmo. Se abbiamo commesso qualche errore nello scrivere il programma precedente, il sistema lo segnala ed occorre in tal caso leggere i messaggi che sono stati generati. Per visualizzarli necessario digitare MSG nella riga comando (cfr. figura 9.13). Otteniamo cos la visualizzazione esplicita dei messaggi di errore. Consigliamo di dare il comando CLEAR dopo averli letti, affinch eventuali messaggi successivi non si confondano con quelli precedenti. Si esce al solito con il comando END o con l'apposito PFK.

339

PROVA.CALC Command ===> msg ERROR: Fatal runtime error detected. Please read MSG screen. PREZZO PEZZI COSTO IVA TOTALE SVILUPPO STAMPA CARTA FILTRO LAMPADE 3000 350 10000 8000 40000 10 95 4 3 2

Run Mode

-------------------------------- PROVA.PGM -------------------------------Command ===> Text Editor Col 001 079 costo=prezzo*pezzo; iva=18; totale=costo+costo*iva/100;

Figura 9.13: Segnalazione di errore nel programma Dalla figura 9.14 notiamo che il programma non stato eseguito correttamente poich abbiamo inavvertitamente fatto riferimento ad una variabile non presente nell'archivio (abbiamo digitato PEZZO invece che PEZZI). Apportate le correzioni necessarie e fatto eseguire nuovamente il programma, otterremo i risultati desiderati che sono mostrati in figura 9.15. Possiamo chiudere a questo punto il programma (con il solito comando END).
Message Screen Command ===> Please use scroll keys to view the messages.

NOTE: Compile Time 0.03 seconds. NOTE: Resolve Time 0.00 seconds. 1 ERROR: Program was executing statement at LINE 1 COLUMN 1 . ERROR: You have referenced PEZZO as an array. ERROR: However, no value assigned prior to this statement. -------------------------------- PROVA.PGM -------------------------------Command ===> Text Editor Col 001 079 costo=prezzo*pezzo; iva=18; totale=costo+costo*iva/100;

Figura 9.14: Spiegazione dell'errore del programma Per concludere occorre osservare che, quando usciamo dall'ambiente "Run mode", scopriamo (cfr. figura 9.16) che nel direttorio del nostro catalogo sono stati creati vari membri: la tabella vera e propria (PROVA.CALC), il programma simbolico (PROVA.PGM), il relativo programma eseguibile (PROVA.EXE) e la base dei parametri da utilizzare per le definizioni delle tabelle (FSCALC.PARMS).

340

PROVA.CALC Command ===> PREZZO SVILUPPO STAMPA CARTA FILTRO LAMPADE 3000 350 10000 8000 40000 PEZZI 10 95 4 3 2 COSTO 30000 33250 40000 24000 80000 IVA 18 18 18 18 18 TOTALE 35400 39235 47200 28320 94400 Run Mode

--------------------------------- PROVA.PGM ------------------------------Command ===> Text Editor Col 001 079 costo=prezzo*pezzi; iva=18; totale=costo+costo*iva/100;

Figura 9.15: Tabella dopo l'esecuzione del programma

Directory for Catalog: WORK.CATMIO Command ===> NOTE: PROVA.PGM has been saved Name Type Description _ _ _ _ PROVA PROVA FSCALC PROVA CALC EXE PARMS PGM PROVA.CALC INTERMEDIATE CODE PROC FSCALC PARAMETERS PROVA.PGM

Updated 26JUN88 26JUN88 26JUN88 26JUN88

Figura 9.16: Contenuto del catalogo a fine sessione

341

10. Cenni di SAS/GRAPH

10.1.

Generalit del SAS/GRAPH

Quando il SAS/GRAPH fece la sua prima comparsa, sia pure in una versione meno flessibile e potente di quella attualmente disponibile, esso conteneva alcuni elementi innovativi, che conservano, ancora oggi, la loro validit. Ne vogliamo ricordare due fra tutti, capaci di spiegare l'enorme successo che gli utenti SAS hanno decretato a questo prodotto. Per prima cosa, la componente SAS/GRAPH perfettamente integrata col resto del mondo SAS. Questo significa che un utente SAS pu ottenere in modo immediato un istogramma, un plot o un grafico tridimensionale, facendo elaborare ad una opportuna PROC archivi SAS gi esistenti, senza bisogno di apportare ai dati alcuna modifica. Una seconda peculiare caratteristica del SAS/GRAPH consiste nel poter utilizzare, in modo del tutto trasparente, un grande numero di apparecchiature di restituzione grafiche. Per ottenere questo risultato, sono disponibili all'interno del SAS/GRAPH dei programmi di interfaccia, chiamati "drivers" , ciascuno dei quali specializzato per "colloquiare" con un determinato dispositivo. Per utilizzare il SAS/GRAPH indispensabile disporre di una apparecchiatura di restituzione che possieda caratteristiche grafiche (stampante, terminale, plotter ecc.) e che sia supportata dal SAS/GRAPH. L'utente ha il solo compito di specificare, al variare della apparecchiatura di restituzione su cui il grafico deve essere visualizzato, il nome del "driver" relativo, lasciando tutto il resto del programma e dei dati inalterato. La componente SAS/GRAPH ha beneficiato con le ultime versioni di una variet molto estesa di nuove funzioni, che l'hanno trasformata in uno strumento potente e versatile; attualmente ne esistono due versioni, perfettamente compatibili fra loro, la prima funzionante su mainframe e minicomputer, la seconda su Personal Computer. Oltre alla possibilit gi descritta di poter gestire un esteso numero di apparecchiature grafiche in modo totalmente trasparente 342

all'utente, altre caratteristiche comuni alle due versioni sono le seguenti: disponibilit di una estesa gamma di uscite grafiche, quali istogrammi, carte tematiche, plot, ecc. ; possibilit di memorizzare in opportuni archivi su disco, detti cataloghi, i grafici ottenuti, in modo da poterli visualizzare successivamente su apparecchiature, anche diverse da quella con cui sono stati generati, o di alterarne alcune caratteristiche quali colori, dimensione, modo di presentazione (funzione TEMPLATE), ecc. ; possibilit di aggiungere scritte, disegni, ecc., in qualunque parte di un grafico (funzione ANNOTATE); possibilit di scrivere titoli, note di fine pagina e testi con diversi stili, colori, altezze dei caratteri, ecc.; possibilit di creare e memorizzare proprie fonti di caratteri.

10.2.

Panoramica delle principali procedure

La componente SAS/GRAPH si compone di circa 20 nuove procedure, introduce alcune nuove dichiarazioni, soprattutto destinate al controllo dei grafici, ed aggiunge nuove opzioni ad altre dichiarazioni gi presenti nel sistema SAS, come la TITLE e la FOOTNOTE. Ciascuna procedura, a sua volta, comprende numerose opzioni che permettono di personalizzare i grafici in funzione delle esigenze. In questo capitolo non scenderemo ad esplorare le singole opzioni; ma una regola generale deve essere sottolineata: il sistema SAS/GRAPH uno strumento cos potente e flessibile che pu disorientare un utilizzatore alle prime armi a causa dalle moltissime personalizzazioni che le varie procedure consentono di effettuare. E' assolutamente sconsigliato, all'inizio, di avventurarsi a provare tutte le varie opzioni di una procedura nel tentativo di apportare miglioramenti sempre pi infinitesimi ai grafici che si stanno producendo; pu essere invece opportuno scegliere fra le seguenti alternative: discostarsi meno possibile dai valori standard delle singole procedure; prendere come riferimento i passi di PROC gi realizzati da altri utenti pi esperti, se esistono nell'ambito del proprio ambiente di lavoro, oppure dagli esempi del manuale di riferimento del sistema SAS/GRAPH o, infine, dalla libreria di esempi che viene distribuita insieme al prodotto da SAS Institute Inc.; usare il prodotto su personal in modo interattivo, rispondendo alle domande poste dai menu relativi a 343

ciascuna PROC, e poi, una volta visto il risultato, verificare come le richieste sono state tradotte in opzioni SAS. Descriviamo ora brevemente alcune delle procedure disponibili, che possono raggrupparsi nelle seguenti 5 aree: 1) Produzione di istogrammi e plot

Le procedure relative sono rispettivamente la PROC GCHART e la PROC GPLOT che sono funzionalmente equivalenti alla PROC CHART e PROC PLOT della componente base del SAS. La prima di queste procedure usata per produrre istogrammi(bar chart) verticali od orizzontali, diagrammi a blocchi (block chart), ideogrammi circolari (pie chart) o stellari (star chart) . La seconda procedura molto potenziata rispetto alla corrispondente PROC PLOT della componente base del SAS; oltre all'uso molto esteso che si pu fare del colore, essa prevede, fra l'altro, i seguenti miglioramenti: i punti sul plot possono essere congiunti mediante linee rette oppure utilizzando sofisticati metodi di "smoothing"; si possono specificare le caratteristiche dell'analisi di regressione da usare per adattare una linea ai punti sul plot ; si possono tracciare livelli di confidenza; si pu generare un secondo asse verticale sul lato destro del plot; si possono utilizzare vari tipi di scale logaritmiche; si possono scegliere fino a 64 simboli diversi per rappresentare i punti sul plot. 2) Produzione di grafici tridimensionali

Le procedure relative sono la PROC GCONTOUR e la PROC G3D. La prima PROC produce plot di "contorno" relativi a tre variabili in due dimensioni in modo analogo alla opzione CONTOUR della PROC PLOT; essa permette di scegliere colori, forme di linee e "pattern" (modalit con cui devono essere riempite le aree) fino a 100 livelli di contorni. La seconda PROC usata per produrre plot di superfici "Surface plot" o plot di punti "Scatter plot" relativi a tre variabili in tre dimensioni. Per rendere visibili eventuali picchi e valli risultanti sui grafici prodotti, possibile specificare angoli di rotazione rispetto all'asse Z, oppure di inclinazione rispetto all'asse Y.

344

3)

Produzione di carte tematiche

In molti campi, l'utilizzo di carte tematiche fornisce uno strumento di lettura e di interpretazione dei dati molto immediato, soprattutto per le applicazioni che interessano il territorio. Per realizzare una carta tematica in SAS/GRAPH sono necessari due archivi: il primo deve contenere le coordinate geografiche delle aree elementari (che a seconda delle applicazioni possono essere i comuni di una provincia, le province di una regione, ecc.) mentre il secondo deve associare alle aree elementari i valori di una variabile "tematica" che si vuole rappresentare sulla carta. L'archivio delle coordinate pu essere pu essere un archivio gi predisposto da ditte specializzate, oppure pu essere costruito dall'utente. In tal caso egli deve digitizzare tutti i tratti, utilizzando un digitizer, prelevandoli da una carta geografica, e deve poi associare a ciascuna area l'insieme dei tratti che la racchiudono8. In particolare SAS Institute Inc. distribuisce, insieme al software SAS/GRAPH, le varie nazioni europee, fra cui l'Italia, digitizzate a livello di regioni e/o province. La principale procedura in questo settore la PROC GMAP, che produce quattro tipi di carte diverse: carte di tipo "choropleth" nelle quali ciascuna area elementare viene colorata in modo diverso; carte di tipo "surface" in cui vengono generate su ogni area elementare dei rilievi di diversa altezza; carte di tipo "block" nelle quali viene disegnato su ciascuna area un parallelepipedo di una determinata altezza; carte di tipo "prism" in cui le singole aree elementari vengono sollevate a diverse altezze. 4) Procedure di presentazione

Queste procedure permettono di produrre testi e grafici, anche in modo combinato, utilizzando le possibilit offerte: dalla nuova dichiarazione NOTE e dalle opzioni aggiunte alle dichiarazioni TITLE e FOOTNOTE; dall'esecuzione dei comandi posti in speciali archivi SAS denominati archivi ANNOTATE; dal processo di composizione di pi grafici sulla stessa pagina (funzione TEMPLATE). Le procedure pi importanti di questo gruppo sono le seguenti: PROC GPRINT che permette di manipolare le uscite prodotte con una qualunque PROC della componente base del SAS, memorizzate su disco, tramite l'aggiunta di titoli e/o note di fine pagina ecc.;
8 Si veda a tal proposito il SAS technical report A-107 dal titolo "Creating your

own SAS/GRAPH map data sets with a digitizer"

345

PROC GSLIDE che permette di ottenere una uscita grafica contenente linee di testo e/o grafici; PROC GREPLAY che permette di presentare su una singola pagina diversi grafici secondo maschere che possono essere create dall'utente (funzione TEMPLATE); PROC GANNO che permette di eseguire i comandi di un archivio ANNOTATE visualizzando i grafici risultanti. 5) Procedure di utilit

Le principali procedure sono: PROC GFONT che permette di costruire delle fonti di caratteri personalizzate; PROC GOPTIONS che elenca tutte le opzioni standard in uso, relative al SAS/GRAPH; PROC GREPLAY che gestisce interattivamente i cataloghi grafici.

10.3. Panoramica dichiarazioni

delle

principali

Per eseguire molte delle funzioni descritte, il SAS/GRAPH fa ricorso ad alcune nuove dichiarazioni e ad alcune nuove opzioni aggiunte a dichiarazioni gi comprese nella componente base del SAS. Cos alle dichiarazioni TITLE e FOOTNOTE sono state aggiunte una serie di opzioni che permettono di specificare il colore, l'altezza, l'angolo e la fonte da usare, le coordinate a cui devono essere scritti i testi, ecc.; le stesse opzioni possono essere specificate nella nuova dichiarazione NOTE. Oltre alla dichiarazione OPTIONS, con la quale si specificano le opzioni da usare, nella componente SAS/GRAPH stata aggiunta la dichiarazione GOPTIONS con cui si specificano le opzioni grafiche. Le principali sono: DEVICE=driver specifica il tipo di apparecchiatura grafica su cui si vuole visualizzare un grafico (es. IBM3279, TEK4014, ecc.); specificano dell'area di restituzione; le dimensioni fisiche

HSIZE=n YSIZE=n HPOS=n VPOS=n

specificano il numero di celle orizzontali verticali in cui si vuol dividere l'area di restituzione;

346

COLORS=(lista ) specifica la lista dei colori da usare e la relativa priorit. L'unica opzione da fornire obbligatoriamente la DEVICE; tuttavia se essa non viene specificata, verr chiesta dallo stesso SAS/GRAPH in modo interattivo, al momento di visualizzare il primo grafico. Le altre dichiarazioni che vengono utilizzate nella maggior parte delle procedure, servono per controllare la forma dei singoli componenti di un grafico; esse sono: AXIS permette di controllare se e come gli assi debbono essere tracciati sui plot e sugli istogrammi; possibile specificare colore, lunghezza, scala, etichette da scrivere, valori delle variabili da riportare, trattini da disegnare, ecc.; permette di controllare se e come debbono comparire le legende nei plot, istogrammi e carte tematiche; possibile specificare colore, forma, dimensioni, ecc.; permette di specificare i colori e forme con cui riempire gli istogrammi, i settori degli ideogrammi circolari o le aree elementari nelle carte tematiche. Questa dichiarazione riveste una importanza particolare e le modalit di uso variano da procedura a procedura; viene utilizzata per controllare il modo con cui i plot vengono realizzati. Permette di specificare i simboli ed i colori da usare per visualizzare i singoli punti, le modalit con cui tracciare le linee che uniscono i vari punti, eventuali richieste di interpolazione, di disegno dei livelli di confidenza, ecc..

LEGEND

PATTERN

SYMBOL

Nessuna di queste dichiarazioni risulta indispensabile; il SAS/GRAPH assumer dei valori standard per quelle dichiarazioni che non sono state specificate.

10.4.

Esempi di alcune PROC

Vedremo ora degli esempi di grafici che possibile ottenere con alcune delle principali procedure del sistema SAS/GRAPH e cio la PROC GCHART, la PROC G3D, la PROC GPLOT ed infine la PROC GMAP. Vedremo anche un esempio della funzione ANNOTATE ed infine una uscita prodotta con la PROC GREPLAY. 347

Al termine del capitolo vengono presentati, per ogni esempio, il relativo passo di PROC, con le principali opzioni e/o dichiarazioni commentate, e la relativa uscita grafica. Eventuali passi di preelaborazione e stampe parziali degli archivi risultanti, sono invece presentati durante la trattazione del presente paragrafo. Non essendo possibile entrare nei dettagli delle singole procedure, questi esempi vanno visti come un piccolo ma significativo "campionario" delle possibilit offerte dal sistema. Tutte le uscite sono state ottenute utilizzando come apparecchiatura grafica un APPLE Macintosh in emulazione di un Tektronics 4010, per mezzo del prodotto VersaTerm-PRO; stata ignorata, per motivi puramente tipografici, una delle principali attrattive offerte dal sistema SAS/GRAPH, e cio il colore. Tutti i programmi sono perfettamente riproducibili su qualunque altra apparecchiatura, ad esempio un terminale grafico IBM 3279, modificando nella dichiarazione GOPTIONS la opzione DEVICE (per l'esempio citato sufficiente specificare DEVICE=IBM3279). Per ottenere invece le uscite a colori, sufficiente eliminare, ancora nella dichiarazione GOPTIONS, l'opzione COLORS=(WHITE). Tutte le procedure fanno riferimento ad un archivio SAS, VENDITE.PAPERONI, che viene creato con il passo di DATA mostrato in figura 10.1.
DATA VENDITE.PAPERONI; DROP I; INPUT ANNO @; DO I = 1 TO 20; INPUT ID MILIARDI @ ; OUTPUT; END; CARDS; 1986 1 .752 2 15.741 6 4.569 7 4.898 11 2.974 12 11.186 16 9.249 17 .958 1987 1 .852 2 18.555 6 6.678 7 4.444 11 3.489 12 12.431 16 10 17 1.321 RUN;

3 8 13 18 3 8 13 18

34.898 12.476 2.832 3.082 38.234 15.341 2.350 3.430

4 9 14 19 4 9 14 19

3.609 11.306 .572 10.783 2.467 15.3 .367 9.770

5 10 15 20 5 10 15 20

15.286 3.229 29.945 12.190 22.323 4.545 22.6 25.450

Figura 10.1: Creazione del file SAS usato negli esempi seguenti Si tratta dei dati consuntivi di una ipotetica azienda che riportano il fatturato, espresso in miliardi di lire, ottenuto in due anni consecutivi su scala regionale. L'archivio SAS risultante VENDITE.PAPERONI contiene 40 osservazioni, ciascuna delle quali contiene 3 variabili numeriche: ANNO ID che pu assumere i valori 1986 e 1987; che pu assumere valori da 1 a 20 corrispondenti alle 20 regioni italiane; 348

MILIARDI che una variabile numerica continua. Definiamo ora in figura 10.2 tre formati di nome CARDINAL, MILIARDI e REGIONI, che verranno in seguito utilizzati negli esempi.
PROC FORMAT; VALUE CARDINAL 1-7 ='NORD' 8-14 ='CENTRO' 15-18 ='SUD' 19,20 ='ISOLE'; VALUE MILIARDI 0 -< 7.5 =' 0-<7.5' 7.5-<12.5 ='7.5-<12.5' 12.5-<17.5 ='12.5-<17.5' 17.5-<22.5 ='17.5-<22.5' 22.5-<27.5 ='22.5-<27.5' 27.5-HIGH ='>27.5'; VALUE REGIONI 1='PIEMONTE' 2='VALDAOSTA' 3='LOMBARDIA' 4='TRENTINO' 5='VENETO' 6='FRIULI' 7='LIGURIA' 8='EMILIA' 9='TOSCANA' 10='UMBRIA' 11='MARCHE' 12='LAZIO' 13='ABRUZZO' 14='MOLISE' 15='PUGLIA' 16='CAMPANIA' 17='BASILICATA' 18='CALABRIA' 19='SICILIA' 20='SARDEGNA';

Figura 10.2: Formati che saranno usate dalle varie PROC La figura 10.9 mostra un esempio della PROC GCHART per ottenere un diagramma a blocchi relativo al fatturato annuo ottenuto nelle 4 aree geografiche Nord, Centro, Sud ed Isole; nel programma viene usato il formato di nome CARDINAL. Come si vede, fatta eccezione per le modalit con cui vengono riempiti i singoli blocchi per mezzo delle dichiarazioni PATTERN, la uscita non appare molto diversa rispetto alla corrispondente PROC CHART. La figura 10.10 mostra un esempio della PROC G3D che produce un grafico contenente le stesse informazioni di quello precedente. Non esiste nella componente base del SAS nessuna procedura equivalente alla PROC G3D. Si pu rilevare come il grafico dia una visione soprattutto qualitativa del fenomeno, senza contenere nessuna indicazione precisa relativa al fatturato delle singole aree. Come si vede dall'esempio, la PROC G3D elabora l'archivio SAS di nome FINALE al posto di quello originale; necessario infatti che ogni osservazione contenga esplicitamente i valori delle variabili che compaiono nella dichiarazione SCATTER (in questo caso AREA, ANNO e TOTALE). Si rende cos indispensabile compiere una preelaborazione dell'archivio di ingresso. Questo esempio evidenzia una delle caratteristiche pi interessanti del sistema SAS, e cio la totale integrazione di tutte le componenti. Uno dei modi per arrivare a questo risultato, consiste nello scrivere un programma SAS, mostrato in figura 10.3, cos strutturato:

349

1) si crea con un passo di DATA un archivio SAS con una nuova variabile, AREA, che pu assumere i valori da 1 a 4 a seconda delle aree geografiche; 2) si ordina l'archivio cos ottenuto per AREA e per ANNO mediante la PROC SORT; 3) si esegue una PROC MEANS sull'archivio cos ordinato, ottenendo in uscita un nuovo archivio SAS di nome FINALE, composto da 8 osservazioni, e tre variabili: AREA, ANNO ed una nuova variabile di nome TOTALE, contenente il totale fatturato annuo di ogni area, esattamente come richiesto dalla PROC G3D.
DATA AREE ; SET VENDITE.PAPERONI; IF 1<= ID <=7 THEN AREA = 1; ELSE IF 8<= ID <= 14 THEN AREA = 2; ELSE IF 15 <= ID <= 18 THEN AREA = 3; ELSE AREA = 4; PROC SORT; BY AREA ANNO; PROC MEANS DATA=AREE SUM NOPRINT; VAR MILIARDI ; BY AREA ANNO; OUTPUT OUT=FINALE SUM=TOTALE; PROC PRINT DATA=FINALE; RUN;

Figura 10.3: Programma SAS che crea l'archivio FINALE La Figura 10.4 mostra l'uscita della PROC PRINT:
OBS 1 2 3 4 5 6 7 8 AREA 1 1 2 2 3 3 4 4 ANNO 1986 1987 1986 1987 1986 1987 1986 1987 TOTALE 79.753 93.553 44.575 53.823 43.234 37.351 22.973 35.220

Figura 10.4: Contenuto dell'archivio FINALE L'esempio di figura 10.11 presenta un'altra applicazione della PROC GCHART. Si vuole ottenere il fatturato globale ottenuto nelle singole regioni, evidenziando i parziali annui. Viene utilizzata la dichiarazione HBAR, ottenendo quindi istogrammi orizzontali, con una serie di opzioni che rendono il risultato finale abbastanza diverso da quello ottenibile utilizzando le opzioni standard. Viene utilizzato il formato di nome REGIONI per ottenere una uscita maggiormente leggibile. 350

Il prossimo esempio in figura 10.12 si propone di ottenere un istogramma in cui siano rappresentati non pi i valori assoluti del fatturato, ma i valori percentuali ottenuti ciascun anno nelle 4 aree geografiche. Viene utilizzata ancora la PROC GCHART, ed in particolare la dichiarazione VBAR ottenendo quindi istogrammi verticali. Poich il dato che si desidera istogrammare non presente nell'archivio originale, si rende necessaria una preelaborazione dei dati al fine di aggiungere una nuova variabile, PERC, che poi sar utilizzata per realizzare il grafico finale. Il relativo passo di DATA mostrato in figura 10.5.
DATA PERC (KEEP = PERC ID ANNO); IF _N_ = 1 THEN DO; DO UNTIL (EOF=1) ; SET VENDITE.PAPERONI END=EOF; IF ANNO=1986 THEN TOT86+MILIARDI; IF ANNO=1987 THEN TOT87+MILIARDI; END; END; SET VENDITE.PAPERONI; /*legge dalla 1a osservazione*/ IF ANNO = 1986 THEN PERC=100*MILIARDI/TOT86; IF ANNO = 1987 THEN PERC=100*MILIARDI/TOT87; RUN;

Figura 10.5: Creazione del file PERC usato nell'esempio di figura 10.10 Si noti che durante la prima esecuzione del passo di DATA viene letto tutto l'archivio VENDITE.PAPERONI per creare le variabili TOT86 e TOT87; la seconda dichiarazione SET ricomincia a leggere l'archivio dalla prima osservazione. L'uscita grafica evidenzia che gli istogrammi relativi alle medesime aree geografiche sono riempite con pattern uguali; se si riesamina la figura 10.9 si noter che in quel caso veniva usato lo stesso pattern per tutti gli istogrammi relativi ad uno stesso anno. L'opzione che permette queste diverse scelte la PATTERNID. Si noti infine che l'asse verticale privo di qualsiasi etichetta e che sono presenti delle linee di riferimento, parallele all'asse orizzontale, per facilitare la lettura. Il prossimo esempio in figura 10.13 mostra ancora la PROC GCHART, e fa utilizzo della dichiarazione PIE ottenendo quindi ideogrammi circolari. Il grafico risultante interessante perch contiene sia le informazioni relative al fatturato di figura 10.9, sia le informazioni relative alle percentuali di figura 10.12, senza che sia stata necessaria nessuna pre-elaborazione dei dati. Negli esempi precedenti si visto che le uscite relative alle dichiarazioni HBAR, VBAR e BLOCK sono essenzialmente simili alle corrispondenti della PROC CHART. 351

Per quanto riguarda invece la funzione PIE, nonostante che in questo esempio siano comprese solo alcune delle possibili opzioni, non pu sfuggire la enorme differenza, in termini di qualit del grafico risultante, rispetto all'analoga funzione PIE della PROC CHART, anche senza l'ausilio del colore. Il prossimo esempio, in figura 10.14, mostra una applicazione della PROC GPLOT. Si vuole ottenere un grafico in cui compaiano due curve distinte, relative ai fatturati annui di ogni regione. Si nota che il grafico risultante poco leggibile, perch sull'asse delle ascisse compaiono i codici delle regioni anzich i loro nomi; se anche si usasse il formato REGIONI di figura 10.2, i nomi delle regioni verrebbero scritti verticalmente a causa del poco spazio disponibile. Per migliorare in modo sensibile la leggibilit del plot, occorre utilizzare uno strumento che stato inserito solo recentemente nel sistema SAS/GRAPH, la funzione di ANNOTATE che, come gi detto permette di aggiungere scritte e/o disegni in una qualunque parte di un grafico. Si deve creare, con un passo di DATA un archivio SAS (nell'esempio di figura 10.6 stato chiamato ANNOTA) contenente tante osservazioni quanti sono i comandi che dovranno essere eseguiti quando l'archivio ANNOTA verr richiamato dalla PROC GPLOT.
DATA ANNOTA; /* crea il file SAS per la ANNOTATE LENGTH TEXT $40 ; /* massima lunghezza dei testi XSYS='2'; YSYS='2';/* definisce sistema di riferimento FUNCTION='LABEL'; /* definisce il comando da eseguire STYLE='XSWISS'; /* definisce la fonte da usare POSITION='6'; /* indica le modalit` di scrittura IF _N_ = 1 THEN DO; X=3; Y=74; TEXT='MILIARDI FATTURATI NEGLI ANNI ''86 ED ''87'; OUTPUT; /* prepara la prima riga del titolo X=7; Y=66; TEXT='Legenda delle Regioni'; OUTPUT; END; /*prepara la seconda riga del titolo STYLE = 'NONE' ; INPUT TEXT & $ X Y @@;/*legge nomi e coordinate regioni OUTPUT; /*prepara 20 comandi per stampare CARDS; /* le regioni alle coordinate X Y 1 Piemonte 2 60 2 Valdaosta 2 57 3 Lombardia 2 4 Trentino 2 51 5 Veneto 2 48 6 Friuli 7 7 Liguria 7 57 8 Emilia 7 54 9 Toscana 7 10 Umbria 7 48 11 Marche 11 60 12 Lazio 11 13 Abruzzi 11 54 14 Molise 11 51 15 Puglia 11 16 Campania 15.5 60 17 Basilicata 15.5 57 18 Calabria 15.5 54 19 Sicilia 15.5 51 20 20 Sardegna 15.5 48 RUN; */ */ */ */ */ */

*/ */ */ */ */ 54 60 51 57 48

Figura 10.6: Creazione del file contenente i comandi per la ANNOTATE In questo semplice caso l'archivio ANNOTA si compone di 22 osservazioni che richiamano tutte lo stesso comando, la funzione 352

'LABEL', e specificano ogni volta una diversa stringa da stampare a partire da una opportuna coppia di coordinate coordinate X/Y. Le ultime due righe dei dati di figura 10.6 non seguono lo stesso incolonnamento delle altre solo per motivi tipografici. Tuttavia tutti i dati sono letti perfettamente dal sistema SAS grazie alla INPUT a lista contenente il modificatore di formato "&" (si notino i due o pi spazi dopo ciascuna regione) ed un "doppio at" (@@) finale (si confronti l'esempio mostrato nel paragrafo 5.5). La PROC GPLOT di figura 10.15, tramite l'opzione ANNOTATE=ANNOTA, aggancia l'archivio di comandi precedentemente creato e li esegue tutti. Si noti che i valori X e Y specificati per scrivere le righe di testo, fanno riferimento ai valori che compaiono sugli assi X ed Y. L'esempio mostrato in figura 10.16 relativo alla creazione di una carta tematica per mezzo della PROC GMAP. Come gi detto, si deve preventivamente creare un archivio SAS contenente le coordinate delle aree elementari che si vogliono rappresentare. Il primo passo del programma di figura 10.7 legge da un archivio grezzo, contenente ad esempio il risultato di una digitizzazione, le coordinate relative alle 20 regioni italiane e crea un archivio SAS di nome CARTA.ITALIA; detto archivio contiene 3 variabili e 1363 osservazioni. ll secondo passo crea invece l'archivio SAS che associa alle varie aree elementari il valore tematico da rappresentare graficamente. Tale file si chiama DATI87 ed estratto dall'archivio VENDITE.PAPERONI con una dichiarazione IF subsetting che preleva i soli dati relativi al 1987.
X FILEDEF REGIONI DISK ITALIA INPUTSAS A; DATA CARTA.ITALIA ; INFILE REGIONI; INPUT ID X Y ; DATA DATI87 ; KEEP ID MILIARDI; SET VENDITE.PAPERONI; IF ANNO=1987; PROC PRINT DATA=CARTA.ITALIA; TITLE 'ARCHIVIO DELLE COORDINATE'; PROC PRINT DATA=DATI87; TITLE 'ARCHIVIO TEMATICO'; RUN;

Figura 10.7: Creazione dell'archivio geografico e di quello tematico E' indispensabile che vi sia una corrispondenza biunivoca fra aree elementari e valori tematici; essa resa possibile da una variabile comune ad entrambi gli archivi, avente caratteristiche e valori identici, che nell'esempio si chiama ID ed assume valori da 1 a 20 in entrambi gli archivi.

353

Il risultato parziale della PROC PRINT, relativo all'archivio delle coordinate CARTA.ITALIA, ed il contenuto dell'archivio tematico DATI87 sono mostrati in figura 10.8.

ARCHIVIO DELLE COORDINATE OBS ID X Y /* inizio 1a area elementare */ /* Piemonte (ID=1) */

1 1 939 20421 2 1 831 20542 ................... 21 1 1002 20557 22 1 939 20421 23 2 1505 20380 24 2 1591 20557 .................... 111 2 988 20340 112 2 1505 20380 1294 20 4706 7177 1295 20 4548 7339 ..................... 1362 20 4797 7287 1363 20 4706 7177 ARCHIVIO TEMATICO OBS 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ID 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 MILIARDI 0.852 18.555 38.234 2.467 22.323 6.678 4.444 15.341 15.300 4.545 3.489 12.431 2.350 0.367 22.600 10.000 1.321 3.430 9.770 25.450

/* fine Piemonte */ /* inizio 2a area elementare */ /* Valdaosta (ID=2) */

/* fine Valdaosta */ /* inizio ultima area */ /*elementare: Sardegna(ID=20)*/

/* fine

Sardegna

*/

Figura 10.8: Stampa parziale dell'archivio geografico e di quello tematico Si noti che i valori X ed Y della prima e dell'ultima osservazione relativa a ciascuna regione nell'archivio delle coordinate sono identici.

354

Il prossimo esempio di figura 10.17, logicamente simile all'esempio precedente. Viene cambiata solo la forma del grafico e la legenda, per mezzo del formato di nome MILIARDI, mostrato in figura 10.2.

Quando il sistema SAS/GRAPH viene usato in modo interattivo, ogni volta che un grafico viene visualizzato, una copia del grafico stesso viene memorizzata in modo automatico su un archivio SAS temporaneo che viene cancellato al termine della sessione SAS. Questo archivio, che su richiesta dell'utente pu essere anche permanente, prende il nome di catalogo grafi- co. Come detto la procedura che gestisce i cataloghi grafici la PROC GREPLAY, di cui viene fornito un esempio in figura 10.18. Questa procedura tipicamente interattiva, e l'uso facilitato da menu e da tasti funzionali. Nell'esempio si possono vedere 4 dei grafici gi visualizzati, disposti secondo una "maschera" costruita interattivamente (template). Sar il SAS/GRAPH ad adattare ciascun grafico alle dimensioni della "maschera". Una volta costruita, una "maschera" pu essere memorizzata in un apposito catalogo per essere richiamata successivamente; un catalogo contenente circa trenta "maschere" gi predisposte da SAS Institute Inc., disponibile a tutti gli utenti.

355

GOPTIONS DEVICE=TEK4010 NOTEXT82 COLORS=(WHITE); OPTIONS PROMPTCHARS='110A010D05000000'X; PROC GCHART DATA=VENDITE.PAPERONI ; TITLE 'MILIARDI FATTURATI DALLA DITTA PAPERONI PER AREA'; LABEL ID='AREA GEOGRAFICA'; FORMAT ID CARDINAL. ; PATTERN1 V=S ; /*definizione primo pattern */ PATTERN2 V=E ; /*definizione secondo pattern */ BLOCK ID /*diagramma a blocchi relativo alla variab. ID*/ / DISCRETE /*i valori della variabile ID sono discreti */ SUMVAR=MILIARDI /*ciascun istogramma rappresenta la..*/ TYPE =SUM /*.somma dei valori della variab. MILIARDI*/ GROUP=ANNO /*grafico ripetuto per ogni valore di ANNO*/ PATTERNID=GROUP /*pattern cambia al variare dell'anno*/ NOHEADING ; /*elimina scritta "BLOCK CHART OF SUMS"*/ RUN;

MILIARDI FATTURATI DALLA DITTA PAPERONI PER AREA

ANNO

1987 93.553 1986 53.823 37.351 35.22

79.753 NORD

44.575 CENTRO

43.234 SUD

22.973 ISOLE

AREA GEOGRAFICA

Figura 10.9: Esempio della PROC GCHART - dichiarazione BLOCK

356

GOPTIONS DEVICE=TEK4010 NOTEXT82 COLORS=(WHITE); OPTIONS PROMPTCHARS='110A010D05000000'X; PROC G3D DATA=FINALE; SCATTER AREA*ANNO=TOTALE /SHAPE='PILLAR' /*indica la forma da usare per rappresentare i punti GRID /*traccia le linee della griglia su tutti gli assi XTICKNUM=2 /*numero di trattini sull'asse X YTICKNUM=4 /*numero di trattini sull'asse Y ZMIN=0 /*valore minimo sull'asse Z ZMAX=100 ; /*valore massimo sull'asse Z FORMAT AREA CARDINAL.; TITLE1 'FATTURATO ANNUO PER AREA GEOGRAFICA '; LABEL TOTALE = 'MILIARDI'; RUN;

*/ */ */ */ */ */

FATTURATO ANNUO PER AREA GEOGRAFICA

100.00

66.67

33.33 1987

0.00 ISOLE SUD CENTRO NORD 1986

Figura 10.10: Esempio della PROC G3D

357

GOPTIONS DEVICE=TEK4010 NOTEXT82 COLORS=(WHITE); OPTIONS PROMPTCHARS='110A010D05000000'X; PROC GCHART DATA=VENDITE.PAPERONI; TITLE 'MILIARDI FATTURATI PER REGIONE'; LABEL ID='REGIONE'; FORMAT ID REGIONI. ; PATTERN1 V=S; PATTERN2 V=E ;/* definizione dei pattern */ AXIS1 LABEL = NONE; /*criteri per disegnare l'asse X */ HBAR ID / /*istogramma orizzontale della variabile ID */ DISCRETE /*i valori della variabile ID sono discreti */ SUMVAR=MILIARDI /* ogni istogramma rappresenta la ....*/ TYPE=SUM /*.. somma dei valori della variab. MILIARDI*/ SUBGROUP=ANNO /*ogni istogramma evidenzia il fatturato relativo agli anni 1986 e 1987 */ PATTERNID=SUBGROUP /*il pattern cambia se varia l'anno*/ NOSTAT /*omette le statistiche alla destra del grafico*/ RAXIS=AXIS1 /* per l'asse X rimanda alla dichiarazione AXIS1 */ FRAME ; /*il grafico e' racchiuso dentro una cornice */ RUN;

MILIARDI FATTURATI PER REGIONE R EGIONE PI EMONTE VAL DAOSTA LOM BARDIA TR ENTINO VENE TO FRIU LI L IGURIA EMIL IA T OSCANA UMBR IA MARC HE LAZ IO A BRUZZO MOLI SE PUGL IA CA MPANIA BASILICATA CA LABRIA S ICILIA SA RDEGNA 0

1 0
ANNO

20

30

4 0
1986

50

60
1987

7 0

80

Figura 10.11: Esempio della PROC GCHART - dichiarazione HBAR

358

GOPTIONS DEVICE=TEK4010 NOTEXT82 COLORS=(WHITE); OPTIONS PROMPTCHARS='110A010D05000000'X; PROC GCHART DATA=PERC; LABEL ID='AREA'; TITLE1 '% DI FATTURATO NELLE DIVERSE AREE'; FORMAT ID CARDINAL.; AXIS1 LABEL=NONE; /*criteri per disegnare l'asse Y */ PATTERN1 V=S; PATTERN2 V=E; PATTERN3 V=R2; PATTERN4 V=X3; VBAR ID /*istogramma verticale della variabile ID */ /DISCRETE /*i valori della variab. ID sono discreti */ SUMVAR=PERC /*ciascun istogramma rappresenta la ... */ TYPE=SUM /*...somma dei valori della variabile PERC */ GROUP=ANNO /*ripeti il grafico per ogni valore di ANNO*/ PATTERNID=MIDPOINT /*pattern = per valori di ID uguali*/ RAXIS=AXIS1 /*per disegnare l'asse Y vedi dichiarazione AXIS1 */ REF=10 TO 40 BY 10 /*traccia linee di riferim. asse Y */ FRAME ; /*istogramma e' racchiuso dentro una cornice */ RUN;

% DI FATTURATO NELLE DIVERSE AREE


50

40

30

20

10

0
NORD CENTRO SUD 1986 ISOLE NORD CENTRO SUD ISOLE 1987 AREA ANNO

Figura 10.12: Esempio della PROC GCHART - dichiarazione VBAR

359

GOPTIONS DEVICE=TEK4010 NOTEXT82 COLORS=(WHITE); OPTIONS PROMPTCHARS='110A010D05000000'X; PROC GCHART DATA=VENDITE.PAPERONI; LABEL ID='AREA'; FORMAT ID CARDINAL.; TITLE '% DI FATTURATO PER AREA'; PATTERN1 V=PS;PATTERN2 V=PL2;PATTERN3 V=PE;PATTERN4 V=PR2; PIE ID /* ideogramma relativo alla variabile ID */ /DISCRETE /*i valori della variabile ID sono discreti*/ SUMVAR=MILIARDI /* in ogni settore valori di MILIARDI*/ GROUP=ANNO /* grafico ripetuto per ogni valore di ANNO */ VALUE=OUTSIDE /* scrivi valori di MILIARDI e le ... */ PERCENT=OUTSIDE/* ... percentuali fuori dei settori */ EXPLODE=8-14 /*evidenzia settore con valori di ID 8-14*/ NOHEADING; /*elimina scrittura SUM OF MILIARDI BY ID*/

% DI FATTURATO PER AREA


ANNO=1986 NORD 79.8 41.86%

CENTRO 44.6 23.39% SUD 43.2 22.69% ANNO=1987 NORD 93.6 42.53%

ISOLE 23.0 12.06%

CENTRO 53.8 24.47% SUD 37.4 16.98%

ISOLE 35.2 16.01%

Figura 10.13: Esempio della PROC GCHART - dichiarazione PIE

360

GOPTIONS DEVICE=TEK4010 NOTEXT82 COLORS=(WHITE); OPTIONS PROMPTCHARS='110A010D05000000'X; PROC GPLOT DATA=VENDITE.PAPERONI; PLOT MILIARDI*ID=ANNO /*tanti plot MILIARDI*ID quanti sono i valori della variabile ANNO */ / FRAME /*il plot e' racchiuso in una cornice */ VAXIS=AXIS1; /*per l'asse Y vedi dichiarazione AXIS1*/ AXIS1 LABEL=NONE; /* asse delle Y senza etichette */ SYMBOL1 I=JOIN L=24 V=STAR; /*unisce gli "asterischi" relativi al 1986 con una linea tratteggiata */ SYMBOL2 I=JOIN L=1 V=SQUARE; /*unisce i "quadratini" relativi al 1987 con una linea unita */ LABEL TITLE1 RUN; ID='REGIONE'; 'MILIARDI FATTURATI NEGLI ANNI 1986 E 1987';

MILIARDI FATTURATI NEGLI ANNI 1986 E 1987

40

30

20

10

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 18 19 20 7
REGIONE 1986 1987

Figura 10.14: Esempio della PROC GPLOT

361

GOPTIONS DEVICE=TEK4010 NOTEXT82 COLORS=(WHITE); OPTIONS PROMPTCHARS='110A010D05000000'X; TITLE1 ; PROC GPLOT DATA=VENDITE.PAPERONI ANNOTATE=ANNOTA; /*richiama il data set di Annotate*/ PLOT MILIARDI*ID=ANNO /*tanti plot MILIARDI*ID .. */ /*.. quanti sono i valori della variab. ANNO*/ / FRAME /*il plot e' racchiuso in una cornice */ VAXIS=AXIS1; /*vedi dichiarazione AXIS1 per asse Y*/ AXIS1 ORDER= 0 TO 75 BY 15 /*specifica i valori dell'asse Y e ...*/ LABEL=NONE ; /*... non deve scrivere etichette */ SYMBOL1 I=SPLINE L=24 V=STAR; /*interpola i punti relativi al 1986 */ SYMBOL2 I=SPLINE L=1 V=SQUARE;/*interpola i punti relativi al 1987 */ LABEL ID='REGIONE'; RUN;

75

MILIARDI FATTURATI NEGLI ANNI '86 ED '87 Legenda delle Regioni 1 Marche 1 1 Lazio 2 1 Abruzzi 3 1 Molise 4 1 Puglia 5 16 17 18 19 20 Ca mpania Ba silica ta Ca labria Si cilia Sa rdegna

60

45

1 Piemo nte 2 Valda osta 3 Lomba rdia 4 Trent ino 5 Venet o

6 Friu li 7 Ligu ria 8 Emil ia 9 Tosc ana 10 Umb ria

30

15 . 0 1 2 3 4 5 ANNO 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 REGIONE 1 986 1987

Figura 10.15: Esempio della PROC GPLOT ed ANNOTATE

362

GOPTIONS DEVICE=TEK4010 NOTEXT82 COLORS=(WHITE); OPTIONS PROMPTCHARS='110A010D05000000'X; /* Definizione dei 5 pattern da usare */ PATTERN1 V=S ; PATTERN2 V=L1; PATTERN3 V=R5; PATTERN4 V=E ; PATTERN5 V=R1; /* Definizione pattern per riempire le aree elementari */ PATTERN6 V=ME; TITLE1 F=XSWISS 'FATTURATO 1987 DELLA DITTA PAPERONI'; PROC GMAP MAP=CARTA.ITALIA /*richiama l'archivio geografico */ DATA=DATI87 /*richiama l'archivio tematico */ ALL; /*tutte le aree sono disegnate */ ID ID; /*stabilisce la corrispondenza fra archivio geografico e tematico */ BLOCK /*stabilisce la forma della carta */ MILIARDI ; /*stabilisce la variabile tematica */ RUN;

FATTURATO 1987 DELLA DITTA PAPERONI

MILIARDI

0 24

8 32

16

Figura 10.16: Esempio della PROC GMAP - dichiarazione BLOCK

363

GOPTIONS DEVICE=TEK4010 NOTEXT82 COLORS=(WHITE); OPTIONS PROMPTCHARS='110A010D05000000'X; /*Vengono definiti i 6 pattern (devono cominciare con M)*/ PATTERN1 V=ME; PATTERN2 V=MS; PATTERN3 V=M1X20; PATTERN4 V=M1N135; PATTERN5 V=M1N45; PATTERN6 V=M1N0; PROC GMAP MAP=CARTA.ITALIA /* richiama l'archivio geografico */ DATA=DATI87 /*richiama l'archivio tematico */ ALL; /*tutte le aree sono disegnate */ ID ID ; /*stabilisce la corrispondenza fra archivio geografico e tematico */ PRISM /*stabilisce la forma della carta */ MILIARDI /*stabilisce la variabile tematica */ / MIDPOINTS = 5 TO 30 BY 5; /*suddivide i valori della variabile MILIARDI in 6 intervalli */ TITLE1 'FATTURATO DELLA DITTA PAPERONI NEL 1987'; FORMAT MILIARDI MILIARDI. ; RUN;

FATTURATO DELLA DITTA PAPERONI NEL 1987

MILIARDI

0-<7.5 7.5-<12.5

12.5-<17.5 17.5-<22.5

22.5-<27.5 >27.5

Figura 10.17: Esempio della PROC GMAP - dichiarazione PRISM

364

Figura 10.18: Esempio della PROC GREPLAY

365

Appendice A: Il SAS Display Manager System (DMS)

Il SAS Display Manager System una componente del sistema SAS che permette all'utente di interagire direttamente con tutte le parti di un job SAS, cio con: il programma; il log (messaggi di errore e note informative SAS); e l'output (risultati dell'elaborazione). Per entrare in ambiente DMS, normalmente si dovr digitare il comando: SAS. Il sistema SAS risponder proiettando sul video una maschera come quella mostrata in figura A.1.
Command ===> SAS(r) Log 27511, 11:42

NOTE: COPYRIGHT (C) 1984,1986 SAS INSTITUTE INC., CARY, N.C. U.S.A. NOTE: CMS SAS RELEASE 5.16 AT CNUCE (02483001). NOTE: CPUID VERSION = FF SERIAL = 001964 MODEL = 3081 .

Versione del SAS 5.16 installata il 9/MAR/87 Per ulteriori informazioni dare il comando HELP NEWS in ambiente SAS.

--------------------------------------------------------------------------Command ===> Program Editor 00001 00002 00003 00004 00005 00006 00007 00008

Figura A.1: Schermata iniziale di una sessione SAS con Display Manager System Come si nota dalla figura A.1, lo schermo diviso in due parti: la porzione superiore, denominata SAS(r) Log ; la porzione inferiore, denominata Program Editor .

Per terminare una sessione SAS DMS baster digitare BYE, sulla linea di comando (alla destra della dicitura COMMAND ===> _) e 366

premere il tasto di ENTER del vostro terminale. Il Program Editor permette di digitare nuovi programmi e dati, richiamare programmi memorizzati precedentemente, modificarli ed inviarli (o sottometterli) per l'esecuzione. Come mostrato in figura A.1, ogni riga numerata si compone di due parti: la numerazione (00001, 00002, ecc.); il resto della riga (inizialmente bianca). La funzione della zona numerata duplice; infatti, oltre che a numerare progressivamente le righe componenti il programma, detta area serve per ospitare eventuali comandi dell'editore, denominati: comandi di linea (line commands ), che verranno descritti in seguito. Il resto della riga serve per ospitare: una dichiarazione SAS; parte di una dichiarazione SAS; pi dichiarazioni SAS; una riga di dati. Per aiutare l'utente a digitare programmi e dati, il DMS mette a disposizione un editore full-screen che accetta le dichiarazioni SAS a partire dalla prima riga del Program Editor segnalata sul margine sinistro da 00001. Saranno visualizzate inizialmente solo le prime otto righe del Program Editor, ma si possono apportare delle personalizzazioni dello schermo (per esempio, richiedere un ampliamento della zona programma), digitando il comando SPLIT nella zona COMMAND dell'area programma. Subito dopo si posizioner il cursore (_) in una qualsiasi linea del video, intesa come linea di separazione tra il Log ed il Programma, e affinch il comando possa essere eseguito si batter il tasto ENTER.

A.1 I comandi di linea (line commands)


L'editore del DMS permette, tramite l'uso di comandi di linea (da digitarsi sul margine sinistro dell'area programma, cio sulla zona numerata): l'inserimento di nuove linee; la cancellazione di linee; la copia di linee, con lo scopo di riportarle altrove; il movimento di linee, con lo scopo di rimuoverle e copiarle altrove; 367

la duplicazione di linee; lo spostamento del contenuto di una o pi linee, di n posizioni a destra o sinistra; ecc.. Dette operazioni sono eseguite inserendo gli appositi comandi riportati in figura A.2. Figura A.2: Principali comandi di linea del Program Editor Comando A B C [n] CC COLS Descrizione Indica la riga dopo la quale si devono muovere o copiare altre linee Indica la riga prima della quale si devono muovere o copiare altre linee Copia una o n linee, prima o dopo una linea di riferimento Copia un blocco di linee compreso da tra due comandi CC Inserisce un righello numerato indicante il numero di colonna. Questa linea speciale non considerata facente parte del testo e pu essere eliminata cancellando la linea o digitando il comando RESET, sulla linea COMMAND Cancella una o n linee a partire dalla linea dove il comando stato inserito Cancella un blocco di linee compreso tra due comandi DD Inserisce una o n linee a partire dalla linea dove il comando stato inserito Inserisce una o pi linee dopo la linea sulla quale il comando stato inserito Inserisce una o pi linee prima della linea sulla quale il comando stato inserito Muove una o n linee in un'altra posizione indicata da un comando di linea A oppure B

D [n] DD I [n] IA IB M [n]

368

MASK

Definisce il contenuto iniziale di una nuova linea. Dopo aver definito la riga di maschera, ogni qualvolta verr inserito un comando I (di inserimento) una riga uguale alla maschera entrer nel testo Muove un blocco di linee in un'altra posizione in base ai comandi A o B Sposta i dati di una riga di uno o pi spazi verso destra, senza possibilit di perdita di dati Sposta i dati posti in un blocco di linee di uno o pi spazi verso destra, senza possibilit di perdita di dati Sposta i dati di una riga di uno o pi spazi verso sinistra, senza possibilit di perdita di dati Sposta i dati posti in un blocco di linee di uno o pi spazi verso sinistra, senza possibilit di perdita di dati Segnala la posizione di una linea che dovr essere sovrapposta a seguito di un comando C, M, CC, MM. I caratteri appartenenti alle linee copiate o mosse sovrapporranno solo quelli delle linee segnate dal comando O solo se questi ultimi sono bianchi o spazi nulli, mentre in caso contrario non ci sar sovrapposizione Segnala un blocco di linee che devono essere sovrapposte a seguito di comandi C, M, CC, MM. Ripete la linea segnata dal comando, una o pi volte (comando di duplicazione) Ripete una o pi volte un blocco di linee. Il blocco de-finito come quel gruppo di linee di cui la prima e l'ultima presentano il comando RR. Per ripetere un blocco n-volte, basta specificare n sul primo o sull'ultimo comando RR

MM > >>

< <<

OO R RR

369

Le figure A.3, A.4, A.5 e A.6 mostrano all'azione alcuni comandi elencati in precedenza.
Command ===> SAS(r) Log 16:48

NOTE: COPYRIGHT (C) 1984,1986 SAS INSTITUTE INC., CARY, N.C. NOTE: CMS SAS RELEASE 5.16 AT CNUCE (02483001). NOTE: CPUID VERSION = FF SERIAL = 001964 MODEL = 3081 .

27511, U.S.A.

---------------------------------------------------------------------------Command ===> Program Editor 00001 00002 00003 00004 00005 I0006 00007 00008 DATA CLASSE; INPUT STUDENTE $ 1-30 SESSO $ ITALIANO 37 LATINO 39; CARDS; ACERBI ANNA F 15 BALLONI ELENA F 15 BERTINI CLAUDIO M 16 GARZELLA ELEONORA F 15

32 ETA 34-35

6 8 5 8

6 7 7 8

<------

Richiesta di inserimento di 1 linea bianca

Figura A.3: Uso del comando di linea I (inserisci linee bianche)

Command ===>

SAS(r) Log

16:58

NOTE: COPYRIGHT (C) 1984,1986 SAS INSTITUTE INC., CARY, N.C. 27511, U.S.A. NOTE: CMS SAS RELEASE 5.16 AT CNUCE (02483001). NOTE: CPUID VERSION = FF SERIAL = 001964 MODEL = 3081 . --------------------------------------------------------------------------Command ===> Program Editor 00001 00002 00003 00004 00005 00006 00007 00008 DATA CLASSE; INPUT STUDENTE $ 1-30 SESSO $ 32 ETA 34-35 ITALIANO 37 LATINO 39; CARDS; ACERBI ANNA F 15 6 6 BALLONI ELENA F 15 8 7 BERTINI CLAUDIO M 16 5 7

Figura A.4: Effetto del comando I

370

Command ===>

SAS(r) Log

17:13

NOTE: COPYRIGHT (C) 1984,1986 SAS INSTITUTE INC., CARY, N.C. 27511, U.S.A. NOTE: CMS SAS RELEASE 5.16 AT CNUCE (02483001). NOTE: CPUID VERSION = FF SERIAL = 001964 MODEL = 3081 . --------------------------------------------------------------------------Command ===> Program Editor 00001 00002 00003 00004 0MM05 00006 00007 0MM08 00009 00010 00011 00012 00013 0A014 00015 ; DATA CLASSE; INPUT STUDENTE $ 1-30 SESSO $ ITALIANO 37 LATINO 39; CARDS; ACERBI ANNA F 15 BALLONI ELENA F 15 BERTINI CLAUDIO M 16 GARZELLA ELEONORA F 15 GHELARDI ALBERTO M 15 MARINI SERGIO M 16 MATTEI DIEGO M 14 SORRI DANILO M 15 ZERBINI RAFFAELE M 16 ZURLETTI ALFIO M 15

32 ETA 34-35

6 8 5 8 7 5 7 6 7 3

6 7 7 8 6 4 6 4 6 3

<------------------| Blocco di linee da muovere <------------------|

<------ dopo questa

Figura A.5: Uso dei comandi di linea MM ed A (muovi un blocco di linee dopo una linea indicata)
--------------------------------------------------------------------Command ===> Program Editor 00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 ; DATA CLASSE; INPUT STUDENTE $ 1-30 SESSO $ ITALIANO 37 LATINO 39; CARDS; GHELARDI ALBERTO M 15 MARINI SERGIO M 16 MATTEI DIEGO M 14 SORRI DANILO M 15 ZERBINI RAFFAELE M 16 ZURLETTI ALFIO M 15 ACERBI ANNA F 15 BALLONI ELENA F 15 BERTINI CLAUDIO M 16 GARZELLA ELEONORA F 15

32 ETA 34-35

7 5 7 6 7 3 6 8 5 8

6 4 6 4 6 3 6 7 7 8

Figura A.6: Effetto dei comandi di linea MM ed A

371

A.2 I comandi della linea COMMAND


Esistono comandi che possono essere digitati nella COMMAND che servono per i seguenti scopi: linea

gestione dell'immagine del video (scrolling commands); gestione degli archivi: programmi e dati (file management commands); gestione editoriale (general editing commands); richiesta di informazioni di ausilio per l'utente (help commands); associazione di comandi a chiavi funzionali (function keys commands); invio di comandi al sistema operativo ospitante il SAS, senza terminare la sessione (host-level commands). La figura A.7 elenca alcuni tra i principali comandi della linea COMMAND. Figura A.7: Alcuni tra i principali comandi della COMMAND-line Comando AUTOEXEC - SASEXEC - fileref Descrizione Permette di inviare su una o pi linee COMMAND del DMS una serie di comandi letti da un archivio esterno (sequenziale o membro di un partitioned). Il primo di detti comandi verr inviato sulla linea di comando sulla quale stata digitato AUTOEXEC. I rimanenti comandi potranno essere riservati ad altre linee di comando, basta farli precedere dalla sigla dell'area in questione (LOG, PROGRAM o OUTPUT). Se nel comando viene specificato un fileref(riferimento logico ad un file esterno), il sistema SAS ricercher il file corrispondente e lo legger tentando di interpretare le righe al suo interno come comandi validi di DMS. Se non viene specificato alcun fileref, il sistema SAS ricercher il file che stato assegnato (in fase di installazione) al fileref di nome SASEXEC. Riporta indietro (srotola o scroll) di un certo numero di righe la parte alta dello schermo.[continua a pag. seguente] 372

BACKWARD

Comando

Descrizione

[continua da pag. precedente] -n La porzione di schermo mossa dipende dal valore imposto da un precedente comando -MAX VSCROLL, dal valore n (numero di righe) o da MAX (srotola per il massimo di righe consentito) BYE Termina la sessione SAS.Il comando pu essere digitato indifferentemente o sulla linea COMMAND del Program Editor o su quella del Log Scorre l'area interessata dal comando (Log, Program Editor o Output sino a quando l'ultima riga del testo non corrisponde all'ultima riga dello schermo dell'area in questione. Questo comando l'inverso di TOP. Il comando seguito dall'opzione ON, fa si che il testo digitato sia convertito in lettere maiuscole quando verr premuto il tasto di invio (ENTER). Un comando successivo utilizzante l'opzione OFF, far s che il testo sia accettato cos come digitato. Cambia in un testo la stringa s1 con s2. Esempio: CHANGE ALBA ALBO. La posizione nella quale si trova la stringa s1 pu essere specificata nel comando stesso. Infatti, NEXT indica che a partire dalla posizione corrente del cursore il sistema ricercher la stringa s1 e una volta trovata la cambier con s2. FIRST e LAST indicano rispettivamente che solo la prima o l'ultima occorrenza di s1 sar cambiata con s2. PREV indica che sar cambiata solo la s1 che si trova prima dell'attuale posizione del cursore nel testo. ALL comander di cambiare tutte le occorrenze di s1 presenti nel testo con s2. Senza ulteriori informazioni il comando CHANGE sostituisce il valore di s1 con quello di s2, indipendentemente dal contesto. PREFIX, SUFFIX e WORD definiscono il contesto nel quale la sostituzione dovr avvenire. PREFIX e SUFFIX, indicano rispettivamente che il cambiamento dovr g 373

BOTTOM

CAPS - ON - OFF

CHANGE s1 s2 - NEXT - FIRST - LAST - PREV - ALL - WORD - SUFFIX - PREFIX

Comando [continua da pag. precedente]

Descrizione avvenire solo quando s1 prefisso o suffisso di una parola. WORD indica che la sostituzione di s1 con s2 dovr avvenire solo quando s1 una parola. Quando si devono cambiare delle stringhe contenenti spazi, occorre racchiuderle tra singolo apice e se la stringa contiene un apice si deve racchiuderla tra doppi apici.

CLEAR

Cancella il contenuto di tutta l'area sulla cui linea di COMMAND stato inviato il comando. Detto comando viene spesso usato in congiunzione con il comando PRINT per stampare solo quei risultati che interessano e non tutta l'area di OUTPUT. Se l'utente posizionato sullo schermo di OUTPUT, l'esecuzione del comando END lo posiziona sulla prima pagina di uscita della prossima procedura. Se non ci sono altre pagine di uscita, viene visualizzato lo schermo iniziale di Program Editor e di Log. Viene utilizzato per individuare una stringa in un testo. Se la stringa contiene caratteri speciali o spazi di riempimento occorre racchiuderla tra due caratteri singolo-apice. NEXT indica che a partire dalla posizione corrente del cursore il sistema ricercher stringa . FIRST e LAST indicano rispettivamente di ricercare solo la prima o l'ultima occorrenza di stringa.. PREV indica che sar cercata solo l'occorrenza che si trova prima dell'attuale posizione del cursore nel testo. ALL comander di contare il numero di volte che stringa appare nel testo. Senza ulteriori informazioni il comando FIND ricerca stringa indipendentemente dal contesto. PREFIX, SUFFIX e WORD definiscono il contesto nel quale la ricerca dovr avvenire. PREFIX e SUFFIX, indicano rispettivamente di individuare stringa solo se essa prefisso o suffisso di una parola. [continua a pag. seguente]

END

FIND stringa

- NEXT - FIRST - LAST - PREV - ALL - PREFIX - SUFFIX - WORD

374

Comando [continua da pag. precedente]

Descrizione WORD indica di individuare stringa solo se una parola. Per parola si intende una stringa di caratteri delimitata da delimitatori. I delimitatori sono quei caratteri che non appartengono alle seguenti categorie: lettere minuscole e maiuscole, numeri ed il carattere '-'.

FORWARD -n - MAX

Riporta in avanti (srotola o scroll ) di un certo numero di righe lo schermo. La porzione di schermo mossa dipende dal valore imposto da un precedente comando VSCROLL, dal valore n (numero di righe) o da MAX (srotola per il massimo di righe consentito). Richiede la visualizzazione di un help in linea, cio di informazioni sul sistema SAS riportate direttamente sul video. In mancanza di altre informazioni detto comando produce la lista degli argomenti che possono singolarmente venire richiesti, digitando la parola chiave relativa dopo HELP. Esempio: HELP DMS produrr informazioni di dettaglio circa il Display Manager System . Permette di prelevare archivi esterni o linee dall'area del SAS Log e di sistemarle nell'area del Program Editor. Le linee prelevate saranno inserite generalmente in fondo alle linee di programma / dati gi presenti nel Program Editor, a meno che non si specifichino punti di inserimento particolari, utilizzando i comandi di linea A,B, oppure O. Per indicare le linee di SAS Log da leggere occorre specificarne il relativo numero nel comando INCLUDE (esempio: INCLUDE 12-37). Nel comando, il parametro fileref rappresenta il nome di riferimento all'archivio. Affinch detto archivio possa essere localizzato opportunamente, occorrer che mediante un apposito comando dipendente dal sistema operativo usato si stabilisca una associazione tra il fileref e i dati che definiscono l'archivio nella sua interezza o ad esempio, nel caso del sistema operativo VM/CMS, [continua a pag. seguente] 375

HELP - parola chiave

INCLUDE

- fileref - fileref(membro) - numero di linea - linea1-linea2

Comando [continua da pag. precedente]

Descrizione volendo assegnare il fileref "DATIN" all'archivio su disco di nome "DATI", tipo "MIEI" e modo "B", occorrer usare il comando CMS di FILEREF nel seguente modo: FILEREF DATIN DISK DATI MIEI B

KEYS

Elenca i tasti funzionali (function keys) ed i relativi comandi associati. Questa associazione pu essere modificata dall'utente, sia per la sola durata della sessione SAS in corso, che permanentemente. Per eliminare dal video la parte di schermo che mostra detta associazione basta digitare END nella linea COMMAND. Definisce la lunghezza della riga dei dati del Program Editor . Il valore n dovr essere un numero compreso tra la lunghezza meno 1 della riga dello schermo del terminale, e 256. Occorre ricordare che se n risulta pi piccolo che la lunghezza della linea contenente i dati avverr un troncamento. Il cursore posizionato sulla linea COMMAND dell'area di Log. Se viene usata l'opzione ON, tutte le linee di dati vengono riempite in fondo con caratteri nulli, invece che con spazi. Questo permetter facilmente di inserire, all'interno di righe, nuovi caratteri senza dover prima: posizionarsi alla fine logica della riga, cancellare la rimanente parte di essa e finalmente procedere con gli inserimenti. L'opzione OFF cambia i caratteri nulli di riempimento con degli spazi. Al primo apparire dell'area del Program Editor la numerazione delle linee dati gi presente. Per eliminarla occorre usare detto comando con l'opzione OFF. Per ristabilirla occorrer usare la ON. Se la numerazione delle righe stata eliminata dallo schermo si possono usare i comandi di linea digitandoli sulla linea COMMAND preceduti dal carattere ":". 376

LINESIZE -n

LOG NULLS

- ON - OFF

NUMS - ON - OFF

OUTPUT

- ON - OFF

Se detto comando non seguito da alcuna opzione, esso genera la sostituzione dell'area di Log con quella di Output . In questo modo sar possibile vedere i risultati dei programmi digitati nell'area di Program Editor. Se viene usata l'opzione ON si comanda al sistema SAS di mostrare i risultati immediatamente mentre la procedura in esecuzione (detta opzione rappresenta il modo di operare standard). L'opzione OFF far si che i risultati siano visibili solo quando, terminata la procedura, l'utente digiter il comando OUTPUT. Comanda la stampa dell'area di video specificata nel comando (PROGRAM, LOG oppure OUTPUT). Tutto il contenuto di dette aree, e non solo la parte visibile sullo schermo verr stampato. L'opzione RECALL fa s che venga stampato il programma sottomesso per ultimo all'esecuzione. Normalmente la stampa viene effettuata sulla stampante definita nella installazione dell'utente come "stampante di sistema", ma possibile memorizzare il contenuto delle aree richieste su un archivio esterno specificando il riferimento all'archivio (fileref) una volta che questo sia stato assegnato all'archivio, tramite un comando di sistema operativo (es.: FILEDEF per il VM/CMS e ALLOCATE per il TSO). Se il comando di PRINT viene inviato senza alcuna opzione, solamente la parte visibile dell'area sulla quale il comando stato inoltrato sar stampata. Per ottenere la stampa di tutta l'area basta aggiungere l'opzione ALL. Sposta il cursore alla linea COMMAND dell'area di Program Editor. Ripete l'azione di individuare una stringa e cambiarla con un'altra in base a quanto specificato precedentemente con un comando di FIND o di CHANGE (vedi: FIND o CHANGE). Estrae l'ultimo programma sottomesso per l'esecuzione e lo inserisce in testa all'area di Program Editor. Inviato sulla linea COMMAND del Program Editor fa s che vengano eliminati gli effetti di precedenti comandi COLS e MASK. 377

PRINT

- PROGRAM - LOG - OUTPUT - RECALL - ALL

PROGRAM RCHANGE

RECALL

RESET

RFIND RULE - ON - OFF

Continua la ricerca della stringa specificata in un precedente comando di FIND o di CHANGE. Se viene usata l'opzione ON, detto comando permette l'inserimento di un righello contacolonne in testa all'area di Program Editor affinch l'utente possa individuare con facilit le colonne iniziali ed inserire i dati al punto giusto. Per rimuovere il righello basta digitare il comando seguito dall'opzione OFF.

Scrive il contenuto dell'area di Program Editor su un archivio assegnato al riferimento fileref. - fileref Questo comando viene usato per salvare i pro- fileref (membro) grammi ed i dati scritti nell'area di programma che potranno essere ripresi successivamente utilizzando il comando INCLUDE. SPLIT Permette il partizionamento dello schermo a discrezione dell'utente. Per questo basta digitare il comando sull'area COMMAND e poi posizionare il cursore sulla riga del video intesa come riga di demarcazione tra l'area di Log e quella di Program Editor, battendo per ultimo il tasto di ENTER. Lo schermo assumer la nuova configurazione voluta. Comanda l'esecuzione del programma scritto nell'area di Program Editor. Scorre l'area interessata dal comando (Log, Program Editor o Output ) sino a quando la prima riga del testo non corrisponda alla prima riga dello schermo dell'area in questione. Questo comando l'inverso di BOTTOM. Permette di inviare comandi al sistema operativo ospitante il SAS. I comandi che seguono la X saranno considerati comandi non per il SAS e saranno inviati al sistema operativo. In ambiente minicomputer detti comandi dovranno essere racchiusi tra due caratteri singolo-apice.

SAVE

SUBMIT TOP

378

Le figure A.8, A.9, A.10, A.11 e A.12 mostrano all'azione alcuni comandi elencati in precedenza.
Command ===> SAS(r) Log 18:24

NOTE: COPYRIGHT (C) 1984,1986 SAS INSTITUTE INC., CARY, N.C. 27511, U.S.A. NOTE: CMS SAS RELEASE 5.16 AT CNUCE (02483001). NOTE: CPUID VERSION = FF SERIAL = 001964 MODEL = 3081 . ------------------------------------------------------------------------Command ===> include libro001 Program Editor 00001 00002

Figura A.8: Uso del comando INCLUDE per portare un programma SAS da file esterno nel Program Editor
Command ===> SAS(r) Log 18:37

NOTE: COPYRIGHT (C) 1984,1986 SAS INSTITUTE INC., CARY, N.C. U.S.A. NOTE: CMS SAS RELEASE 5.16 AT CNUCE (02483001). NOTE: CPUID VERSION = FF SERIAL = 001964 MODEL = 3081 .

27511,

------------------------------------------------------------------------Command ===> Program Editor 00001 00002 00003 00004 00005 00006 00007 00008 DATA CLASSE; INPUT STUDENTE $ 1-30 SESSO $ ITALIANO 37 LATINO 39; CARDS; ACERBI ANNA F 15 BALLONI ELENA F 15 BERTINI CLAUDIO M 16 GARZELLA ELEONORA F 15

32 ETA 34-35

6 8 5 8

6 7 7 8

Figura A.9: Effetto del comando INCLUDE


Command ===> SAS(r) Log 19:22 27511,

NOTE: COPYRIGHT (C) 1984,1986 SAS INSTITUTE INC., CARY, N.C. U.S.A. NOTE: CMS SAS RELEASE 5.16 AT CNUCE (02483001). NOTE: CPUID VERSION = FF SERIAL = 001964 MODEL = 3081 .

------------------------------------------------------------------------Command ===> x flist Program Editor 00001

Figura A.10: Invio di un comando al sistema operativo ospitante VM/CMS

379

LVL 0 --- A 191 AAAREAD ME AAFILES HLP ALL NOTEBOOK ASTRA1 LISTING ASTRA1 SCRIPT ATARI TXT CAMMELLO SAS CAMMELLO SASLOG DISC EXEC ELENCO MAIL KERMSRV DIR KERMSRV INFO LASTING GLOBALV LFC EXEC LIBRO001 SAS LISTAUPD INFO-MAC LOG EXEC MAINTPC EXEC MSKERMIT INI PC78 XEDIT PROFILE EXEC RICEVO EXEC 1=HLP 2=BRW 3=END

465 BLKS ???? R/W A1 A1 A0 A1 A1 A1 A1 A1 A1 A A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 4=XED 5=SPL 6=/SB

30 V V V V V V F V V F F F V V F F V V V V V V 7=SCB

FILES 60% -- FILE 1 OF 30 76 41 2 10/31/86 22:08 79 689 32 7/14/87 20:16 80 1353 109 8/27/87 14:39 62 110 4 9/01/87 14:28 70 59 3 9/01/87 14:28 97 197 9 8/11/87 18:32 80 10 1 8/28/87 17:03 76 33 1 8/28/87 17:08 9 1 1 6/20/87 0:22 80 197 16 7/24/87 9:36 80 28 3 7/28/87 16:24 80 70 6 7/28/87 18:15 24 2 1 9/02/87 17:50 29 2 1 6/12/87 1:14 80 19 2 8/29/87 15:27 80 4 1 5/30/87 18:47 9 1 1 6/20/87 0:21 41 4 1 4/01/87 20:16 17 61 1 7/22/87 10:47 34 14 1 4/03/87 13:35 34 18 1 12/04/86 16:16 58 18 1 4/30/87 18:54 8=SCF 9=/SD 10=/ST 11=>I 12=CA

Figura A.11: Effetto del comando X FLIST

Command ===>

Enter END to return to SAS

Note: For more information enter HELP keyword or HELP HELP Help files Operating systems: All Scroll forward for more information Enter HELP SASHELPO for help with the SASHELP= option. To see a list of the available help keywords, see the Keyword ------AF BASEMISC Notes ----lists keywords for SAS/AF product. lists keywords for the base SAS product miscellaneous topics. lists keywords for SAS display manager commands. lists keywords for SAS/ETS product. lists keywords for SAS/FSP product. following help files:

DMSHELP

ETS FSP

Figura A.12: Effetto del comando HELP (lista parziale di possibilit)

380

A.3 I comandi della linea COMMAND ed i tasti funzionali


Le tastiere dei moderni terminali sono corredate da una serie di tasti funzionali (function keys) ai quali sono associabili comandi della linea COMMAND in modo da evitare all'utente di doverli digitare per esteso, bens di inviarli al DMS mediate la semplice pressione di un tasto. Il DMS prevede una associazione comandi-tasti funzionali definita in partenza; ognuno dei tre ambienti di PROGRAM, LOG e OUTPUT ha una propria associazione comandi-tasti funzionali, ma possibile modificarla a piacere operando cos una personalizzazione dell'ambiente operativo, per la sola durata della sessione in corso oppure permanentemente (vedi comando AUTOEXEC). Per prendere visione, durante la sessione SAS, della associazione comandi-tasti funzionali occorre digitare il comando KEYS nella zona di COMMAND dell'ambiente desiderato. Il DMS mostrer una finestra simile a quella mostrata in fig. A.13; per cambiare l'associazione comandi-tasti funzionali, baster digitare sul lato destro del nome del tasto funzionale il nuovo comando desiderato. Al termine di detta operazione, per ritornare alla finestra di origine, baster digitare il comando END (o il tasto funzionale relativo).
FUNCTION KEY DEFINITIONS COMMAND ===> KEY 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 COMMAND help split; submit recall; rfind rchange backward forward output; left right cursor; help split; submit recall; rfind rchange backward

Fig. A.13: Associazione comandi-tasti funzionali (prodotta dal comando KEYS) 381

Affinch si possa personalizzare la propria sessione di lavoro SAS (ad esempio, assegnando particolari comandi a tasti funzionali, modificando le dimensioni delle finestre dello schermo, cambiando i colori delle aree del video, ecc.) esistono due modalit operative: comandare, al momento dell'inizio della sessione, l'esecuzione dei comandi memorizzati in un archivio esterno (sequenziale o membro di un partitioned) precedentemente associato al fileref di nome SASEXEC. Questo fileref riservato e non deve essere assegnato ad altri archivi usati dal programma. Se, all'inizio della sessione, il sistema SAS non in grado di ritrovare alcun archivio assegnato a SASEXEC, l'ambiente operativo risultante sar quello standard; inviare, in un qualsiasi momento della sessione di lavoro, il comando AUTOEXEC. Detto comando pu essere seguito da un fileref, assegnato precedentemente ad un archivio contenente i comandi DMS di personalizzazione. In mancanza di tale nome il sistema SAS cercher se esiste un siffatto archivio assegnato al fileref riservato SAEXEC. Per ulteriori dettagli in merito si consulti il manuale SAS User's Guide Basics, al capitolo SAS Display Manager.

382

Appendice B: I comandi di sistema

Questa appendice presenta una serie di esempi relativi ai comandi di sistema necessari per: leggere (o scrivere) archivi esterni non SAS; creare archivi SAS permanenti; leggere archivi SAS permanenti. Viene fatta l'ipotesi peggiore per l'utente, che non esista alcun ambiente SAS gi predisposto; in molte realt aziendali, invece esistono delle precise convenzioni relative ai nomi che devono essere usati per stabilire un aggancio fra mondo SAS e sistema operativo. In questi casi fortunati, molto di quanto diremo risulta superfluo per l'utente, che deve solo preoccuparsi di scrivere i programmi SAS limitandosi a seguire le convenzioni stabilite. Verranno presi in esame alcuni fra i pi diffusi tipi di elaboratori su cui disponibile il sistema SAS, con i seguenti sistemi operativi: Tipo di Elaboratore IBM Sistema operativo OS/MVS TSO VM/CMS DOS/VSE VMS MS/DOS

DIGITAL PC

Tutti gli esempi che si riferiscono alla lettura di archivi non SAS (utilizzando la dichiarazione INFILE), possono essere presi come modello anche per la scrittura di archivi non SAS. E' sufficiente scambiare le dichiarazioni INFILE ed INPUT, rispettivamente con FILE e PUT.

383

B.1 Ambiente OS/MVS


Leggere un archivio catalogato di nome "DATI.ANAGRAFE" e creare un archivio SAS temporaneo di nome "ABITANTI".
//nomejob JOB ........ // EXEC SAS //ANAG DD DNS=DATI.ANAGRAFE,DISP=SHR //SYSIN DD * DATA ABITANTI; INFILE ANAG; INPUT NOME $ 1-8 COGNOME $ 10-18 NATO_IL $ 21-30 SESSO $ 34 REDDITO 37-45 FIGLI 49-50 TITOLO 53-54; RUN;

Leggere un archivio catalogato di nome "DATI.ANAGRAFE" e creare un archivio SAS permanente di nome "ABITANTI", nella libreria definita da "SASDATI".
//nomejob JOB ........ // EXEC SAS //ANAG DD DNS=DATI.ANAGRAFE,DISP=SHR //SASDATI DD DSN=SASLIB.DATICENS,DISP=(NEW,CATLG), // UNIT=SYSDA,VOL=SER=WORK01,SPACE=(CYL(1,0)) //SYSIN DD * DATA SASDATI.ABITANTI; INFILE ANAG ; INPUT NOME $ 1-8 COGNOME $ 10-18 NATO_IL $ 21-30 SESSO $ 34 REDDITO 37-45 FIGLI 49-50 TITOLO 53-54; RUN;

Stampare l'archivio SAS permanente "SASDATI.ABITANTI" precedentemente creato.


//nomejob JOB ........ // EXEC SAS //SASDATI DD DSN=SASLIB.DATICENS,DISP=SHR //SYSIN DD * PROC PRINT DATA=SASDATI.ABITANTI; RUN;

di

nome

384

B.2 Ambiente TSO


Leggere un archivio catalogato di nome "DATI.ANAGRAFE" e creare un archivio SAS temporaneo di nome "SASANAG".
X ALLOC F(ANAG) DA('DATI.ANAGRAFE') SHR; DATA SASANAG; INFILE ANAG; INPUT NOME $ 1-8 COGNOME $ 10-18 NATO_IL $ 21-30 SESSO $ 34 REDDITO 37-45 FIGLI 49-50 TITOLO 53-54; RUN;

Leggere un archivio catalogato di nome "DATI.ANAGRAFE" e creare un archivio SAS permanente di nome "ABITANTI", nella libreria definita da "SASDATI".
X ALLOC F(ANAG) DA('DATI.ANAGRAFE') SHR; X ALLOC F(SASDATI) DA ('SASLIB.DATICENS') NEW TRACKS SPACE (5 0); DATA SASDATI.ABITANTI; INFILE ANAG; INPUT NOME $ 1-8 COGNOME $ 10-18 NATO_IL $ 21-30 SESSO $ 34 REDDITO 37-45 FIGLI 49-50 TITOLO 53-54; RUN;

Stampare l'archivio SAS permanente "SASDATI.ABITANTI" precedentemente creato.


X ALLOC F(SASDATI) DA ('SASLIB.DATICENS') SHR ; PROC PRINT DATA SASDATI.ABITANTI; RUN;

di

nome

385

B.3 Ambiente VM/CMS


Leggere un archivio "DATI ANAGRAFE" dal disco A e creare un archivio SAS temporaneo di nome "SASANAG".
X FILEDEF ANAG DISK DATI ANAGRAFE A; DATA SASANAG; INFILE ANAG; INPUT NOME $ 1-8 COGNOME $ 10-18 NATO_IL $ 21-30 SESSO $ 34 REDDITO 37-45 FIGLI 49-50 TITOLO 53-54; RUN;

Leggere un archivio di nome "DATI ANAGRAFE" dal disco B e creare un archivio SAS permanente "ABITANTI SASDATI" sul disco A.
X FILEDEF ANAG DISK DATI ANAGRAFE B; DATA SASDATI.ABITANTI; INFILE ANAG; INPUT NOME $ 1-8 COGNOME $ 10-18 NATO_IL $ 21-30 SESSO $ 34 REDDITO 37-45 FIGLI 49-50 TITOLO 53-54; RUN;

Leggere un archivio di nome "DATI ANAGRAFE" dal disco A e creare un archivio SAS permanente "ABITANTI SASDATI" sul disco B.
X FILEDEF ANAG DISK DATI ANAGRAFE A; X FILEDEF SASDATI DISK SASDATI ABITANTI B; DATA SASDATI.ABITANTI; INFILE ANAG; INPUT NOME $ 1-8 COGNOME $ 10-18 NATO_IL $ 21-30 SESSO $ 34 REDDITO 37-45 FIGLI 49-50 TITOLO 53-54; RUN;

Stampare l'archivio SAS "ABITANTI SASDATI" sul disco A precedentemente creato.


PROC PRINT DATA SASDATI.ABITANTI; RUN;

386

B.4 Ambiente DOS/VSE


Leggere un archivio di nome "DATI.ANAGRAFE" e creare un archivio SAS temporaneo di nome "ABITANTI".
........ // DLBL ANAG,'DATI.ANAGRAFE' // EXTENT SYS027,SASDOS // ASSGN SYS027,DISK,VOL=SASDOS,SHR ........ DATA ABITANTI; INFILE ANAG RECFM=FB LRECL=320 BLKSIZE=3200; INPUT NOME $ 1-8 COGNOME $ 10-18 NATO_IL $ 21-30 SESSO $ 34 REDDITO 37-45 FIGLI 49-50 TITOLO 53-54; RUN;

Leggere un archivio di nome "DATI.ANAGRAFE" e creare un archivio SAS permanente di nome "ABITANTI", nella libreria definita da "SASDATI".
........ // DLBL ANAG,'DATI.ANAGRAFE' // EXTENT SYS027,SASDOS // ASSGN SYS027,DISK,VOL=SASDOS,SHR // DLBL OUTDATI,'SASLIB.DATICENS',99/365 // EXTENT SYS027,SASDOS,1,0,9950,15 // ASSGN SYS027,DISK,VOL=SASDOS,SHR ........ DATA OUTDATI.ABITANTI; /*DEVE iniziare per O*/ INFILE ANAG RECFM=FB LRECL=320 BLKSIZE=3200; INPUT NOME $ 1-8 COGNOME $ 10-18 NATO_IL $ 21-30 SESSO $ 34 REDDITO 37-45 FIGLI 49-50 TITOLO 53-54; RUN;

Stampare l'archivio SAS permanente precedentemente creato.


........ // DLBL INDATI,'SASLIB.DATICENS' // EXTENT SYS027,SASDOS // ASSGN SYS027,DISK,VOL=SASDOS,SHR ........ PROC PRINT DATA INDATI.ABITANTI;/*DEVE iniziare per I*/ RUN;

387

B.5 Ambiente VMS


Leggere un archivio di nome "[RISULT.CENS]DATI.DAT" e creare un archivio SAS temporaneo di nome "SASANAG".
FILENAME ANAG '[RISULT.CENS]DATI.DAT; DATA SASANAG; INFILE ANAG; INPUT NOME $ 1-8 COGNOME $ 10-18 NATO_IL $ 21-30 SESSO $ 34 REDDITO 37-45 FIGLI 49-50 TITOLO 53-54; RUN;

Leggere un archivio di nome "[RISULT.CENS]DATI.DAT" e creare un archivio SAS permanente di nome "ABITANTI", in un sottodirettorio VMS dal nome "[SASDIR.CENS]". In questo caso viene creato l'archivio permanente SAS "[SASDIR.CENS].ABITANTI.SSD".
FILENAME ANAG '[RISULT.CENS]DATI.DAT'; LIBNAME SASDATI '[SASDIR.CENS]' ; DATA SASDATI.ABITANTI; INFILE ANAG; INPUT NOME $ 1-8 COGNOME $ 10-18 NATO_IL $ 21-30 SESSO $ 34 REDDITO 37-45 FIGLI 49-50 TITOLO 53-54; RUN;

Stampare l'archivio SAS permanente precedentemente creato.


LIBNAME SASDATI '[SASDIR.CENS]' ; PROC PRINT DATA SASDATI.ABITANTI; RUN;

388

B.6 Ambiente PC
Leggere un archivio di nome "A:DATI.DAT" e creare un archivio SAS temporaneo di nome "SASANAG".
FILENAME ANAG 'A:DATI.DAT; DATA SASANAG; INFILE ANAG; INPUT NOME $ 1-8 COGNOME $ 10-18 NATO_IL $ 21-30 SESSO $ 34 REDDITO 37-45 FIGLI 49-50 TITOLO 53-54; RUN;

Leggere un archivio di nome "A:DATI.DAT" e creare un archivio SAS permanente di nome "ABITANTI", in un sottodirettorio DOS dal nome "A:\SASDIR". In questo caso viene creato l'archivio permanente SAS "A:\SASDIR\.ABITANTI.SSD".
FILENAME ANAG 'A:DATI.DAT; LIBNAME SASDATI 'A:\SASDIR' ; DATA SASDATI.ABITANTI; INFILE ANAG; INPUT NOME $ 1-8 COGNOME $ 10-18 NATO_IL $ 21-30 SESSO $ 34 REDDITO 37-45 FIGLI 49-50 TITOLO 53-54; RUN;

Stampare l'archivio SAS permanente precedentemente creato.


LIBNAME SASDATI 'A:\SASDIR' ; PROC PRINT DATA SASDATI.ABITANTI; RUN;

389

Appendice C: Bibliografia

Per realizzare il presente testo abbiamo consultato molti volumi della nutrita libreria che documenta il sistema SAS. Di seguito si elencano quelli principali: SAS User's Guide: Basics Il volume contiene tutte le informazioni necessarie per usare il sistema SAS. Rappresenta il manuale di riferimento della componente SAS/BASE. SAS User's Guide: Statistics Il volume contiene tutte le informazioni relative all'uso delle procedure statistiche disponibili nel sistema SAS. SAS Introductory Guide Il volume rappresenta una guida per l'utente che per la prima volta usa il sistema SAS. SAS Application Guide , Edizione 1987 Il volume contiene un notevole insieme di interessanti esempi di applicazione del SAS/Base SAS/GRAPH User's Guide Il volume rappresenta il manuale di riferimento per l'uso della componente SAS/GRAPH. SAS/FSP User's Guide Il volume rappresenta il manuale di riferimento per l'uso della componente SAS/FSP. SAS Guide to TABULATE Processing Il volume rappresenta il manuale di riferimento per l'uso della procedura TABULATE. SAS Guide to Macro Processing Il volume rappresenta il manuale di riferimento per l'uso del 390

linguaggio macro. SAS Companion for OS Operating Systems and TSO, 1984 Edition Il volume documenta le possibilit offerte dal sistema SAS sotto OS e TSO. SAS Companion for CMS Operating Systems , 1986 Edition Il volume documenta le possibilit offerte dal sistema SAS sotto CMS. SAS Companion for VSE Operating Systems , 1987 Edition Il volume documenta le possibilit offerte dal sistema SAS sotto VSE. SAS Companion for VMS Operating Systems , 1986 Edition Il volume documenta le possibilit offerte dal sistema SAS sotto VMS. Inoltre abbiamo reperito dalla letteratura internazionale i seguenti due volumi che, sino ad oggi, hanno rappresentano i soli testi aventi per argomento il sistema SAS scritti da autori indipendenti: Applied Statistics and SAS Programming Language Ronald P. Cody and Jeffrey K. Smith Editore: NORTH-HOLLAND Il volume presenta, in forma alquanto discorsiva, una serie di esempi d'uso del sistema SAS, con particolare riferimento alle applicazioni statistiche. Del testo in questione gi pronta la seconda edizione. An Introduction to Computer Applications in Statistics Delwyn L. Harnisch and Carolyn J. Palmer Editore: STIPES PUBLISHING COMPANY Champaign, Illinois 61820 Il volume tratto dalla parte esercitazioni di un corso di Statistica che prevede l'uso dell'elaboratore dotato del sistema SAS. Al contrario del testo citato in precedenza, questo volume pi che rappresentare un libro didatticamente ben organizzato, presenta le caratteristiche di una raccolta di appunti; infatti esso contiene le uscite prodotte da alcune procedure statistiche presenti nel sistema SAS, nonch una breve interpretazione dei risultati relativi.

391

Appendice D: Elenco marchi registrati e convenzioni

Marchi registrati
SAS, SAS/GRAPH, SAS/FSP, SAS/AF, SAS/ETS, SAS/OR, SAS/QC, SAS/DMI, SAS/IML, SAS/REPLAYCICS, SAS/DB2, SAS/SQL-DS, SAS/DB2,SAS/IMS-DL/I, SAS Communications, SYSTEM 2000, SAS/C, SAS/CX e SASware Ballot sono marchi registrati da SAS Institute Inc. MicroVAX, VAX e VMS sono marchi registrati da Digital Equipment Corp. ECLIPSE un marchio registrato da Data General Corp. PRIMOS un marchio registrato da Prime Computer Inc. BMDP Statistical Software Package un marchio registrato da BMDP Statistical Software Inc. SPSS un marchio registrato da SPSS Inc. MS-DOS un marchio registrato da Microsoft Corp. Quick-Basic un marchio registrato da Microsoft Corp. Macintosh un marchio registrato da Apple Computer Inc. UNIX un marchio registrato da AT&T - Bell Laboratories IBM un marchio registrato da International Businnes Machines Corp. VersaTerm-PRO un marchio registrato da Adelbeck Software TurboProlog un marchio registrato da Borland International Inc. TurboPascal un marchio registrato da Borland International Inc.

392

Convenzioni usate per descrivere la sintassi delle dichiarazioni SAS


Si detto che le dichiarazioni SAS cominciano con una parola chiave (es.: IF, DO, PROC, ecc.), terminano con il carattere ";" e che al loro interno possono trovarsi altre parole chiave (es.: DATA=, NOPRINT, MISSING, ecc.), nomi SAS (es.: nomi di variabili), e caratteri speciali (es.: "$", "%", "(", ecc.). Nel presente testo, per descrivere la sintassi delle dichiarazioni SAS incontrate, abbiamo adottato le seguenti convenzioni: le informazioni scritte in grassetto indicano quelle parti di dichiarazione che devono essere specificate cos come appaiono nelle specifiche del linguaggio: es.: PROC PRINT DATA= ecc. ; le informazioni scritte in corsivo indicano quelle parti di dichiarazione che sono a scelta dell'utente (ad esempio: il nome di una variabile SAS); se queste informazioni si compongono di pi parole, esse sono state racchiuse tra i caratteri "<" e ">": es.: <nome del file SAS> ; pi caratteri punto (".") indicano la presenza, in seguito, di altre informazioni simili: es.: DATA file1 file2 ............ ; le informazioni racchiuse tra due parentesi quadre ([ ... ]) sono da considerarsi non strettamente necessarie: es.: PROC PRINT [DATA= archivio_SAS] ; la barra verticale ("|") indica una scelta alternativa tra le due informazioni poste, rispettivamente, sul lato destro e sinistro di essa: es.: INFILE fileref | CARDS ; la parola opzioni indica la presenza di specifiche opzioni di personalizzazione: es.: PROC MEANS opzioni ; .

393

Vous aimerez peut-être aussi