Comments
Transcript
Imparare - Facoltà di Scienze Statistiche
Imparare SAS Gianluca Della Vedova Dipartimento di Statistica Università di Milano-Bicocca [email protected] http://www.statistica.unimib.it/utenti/dellavedova/ Versione del 21 novembre 2003 Nota Bene. Questo testo non sostituisce in alcun modo il libro di testo del corso “Laboratorio Statistico-Informatico”, inoltre il programma del corso potrebbe non coincidere con il contenuto del presente testo. Copyright (c) 2002-2003 Gianluca Della Vedova è garantito il permesso di copiare, distribuire e/o modificare questo documento seguendo i termini della Licenza per Documentazione Libera GNU, Versione 1.1, pubblicata dalla Free Software Foundation; con Sezione Non Modificabile Ringraziamenti, con i Testi Copertina “Gianluca Della Vedova” e “Imparare SAS”, e senza Testi di Retro Copertina. Una copia della licenza è acclusa nella sezione intitolata Licenza per Documentazione Libera GNU. Indice 1 Introduzione 1.1 Prefazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 Convenzioni tipografiche . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3 La vera introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 I fondamenti 2.1 I linguaggi di programmazione . . . . . . 2.2 Istruzioni condizionali . . . . . . . . . . 2.3 Schema di ciclo produttivo . . . . . . . . 2.4 Il sistema . . . . . . . . . . . . . . . . . 2.5 Sintassi basilare . . . . . . . . . . . . . . 2.6 Il dataset . . . . . . . . . . . . . . . . . 2.7 Relazione fra dataset e filesystem . . . . 2.8 SAS come linguaggio di programmazione 2.9 Le librerie . . . . . . . . . . . . . . . . . 2.10 Operazioni fondamentali su dataset . . . 2.11 Creare un dataset . . . . . . . . . . . . . 2.12 Leggere e salvare un dataset . . . . . . . 2.13 Esportare un dataset . . . . . . . . . . . 2.14 Creare e cancellare variabili . . . . . . . 2.15 Visualizzare un dataset . . . . . . . . . . 2.16 Variabili indicizzate . . . . . . . . . . . . 2.17 Estrarre osservazioni da un dataset . . . 2.18 Istruzioni condizionali . . . . . . . . . . 5 5 5 5 . . . . . . . . . . . . . . . . . . 7 7 8 9 9 11 12 13 14 14 15 16 16 18 20 20 21 22 22 . . . . . . . . 25 25 25 27 29 31 32 33 34 4 Calcolare delle statistiche 4.1 Estrazione di osservazioni significative . . . . . . . . . . . . . . . . . . . 4.2 Altre statistiche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.3 Creare un dataset con le statistiche . . . . . . . . . . . . . . . . . . . . 37 37 39 39 3 Ancora operazioni su dataset 3.1 Introduzione . . . . . . . . . . . . . . . 3.2 Inserire i dati . . . . . . . . . . . . . . 3.3 Array . . . . . . . . . . . . . . . . . . 3.4 Ordinare un dataset . . . . . . . . . . 3.5 Raggruppare osservazioni in un dataset 3.6 Ristrutturare dataset . . . . . . . . . . 3.7 Stampare i dati . . . . . . . . . . . . . 3.8 Riepilogo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Rappresentazioni grafiche 5.1 La proc plot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2 La proc gplot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3 Una migliore rappresentazione testuale . . . . . . . . . . . . . . . . . . 41 41 42 42 6 Dai 6.1 6.2 6.3 6.4 6.5 45 45 45 47 47 47 dati alle informazioni Analisi delle frequenze . La proc corr . . . . . . . Tabelle a 2 entrate . . . Analisi di regressione . . Grafico di regressione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Esercizi riepilogativi 51 8 Soluzioni degli esercizi 53 Elenco dei problemi 55 Elenco dei programmi 56 Elenco delle figure 57 Indice analitico 58 9 Licenza per Documentazione Libera GNU 59 Introduzione 1.1 prefazione Questo libro vuole essere una semplice introduzione a SAS per chi non conosce un linguaggio di programmazione. In quanto tale è adatto all’utilizzo in un corso universitario semestrale. I prerequisiti consistono unicamente nella capacità di usare un elaboratore, in quanto si cercherà di trattare gli argomenti in maniera indipendente dal sistema operativo su cui SAS è installato. 1.2 convenzioni tipografiche Per distinguere un programma SAS anche quando è inserito nel testo, questo sarà scritto nel carattere macchina da scrivere. Le parole riservate di SAS saranno sempre scritte in maiuscolo, ovvero QUESTO è un comando riservato di SAS. I concetti che vengono definiti saranno invece scritti in corsivo. Talvolta nel margine esterno appariranno alcuni approfondimenti. Ogni programma viene scritto in un modo particolare: ogni riga viene preceduta da un numero progressivo scritto con un carattere più piccolo del testo che segue. Tale numero serve solo come riferimento e non è parte del programma vero e proprio. Ogni programma inizia con una intestazione e termina con una riga orizzontale, per meglio separarlo dal testo. 1.3 la vera introduzione Imparare un linguaggio di programmazione non è semplice, ed imparare il primo linguaggio di programmazione è ancora più difficile, ma il fatto che molte persone decidano (con successo) di imparare a programmare fà capire che tale compito è sicuramente alla portata di tutti. SAS è un linguaggio molto particolare, in quanto è stato studiato per l’analisi statistica di dati. Le finalità specialistiche di SAS hanno comportato una serie di scelte nella fase di disegno del linguaggio che lo rendono completamente diverso da tutti gli altri linguaggi di programmazione. Questo libro non intende essere una guida all’uso avanzato di SAS, ma vorrebbe guidare il lettore alla scoperta delle funzionalità basilari di SAS. In particolare si introdurranno inizialmente alcuni costrutti fondamentali, per poi arricchire progressivamente le conoscenze del lettore con approfondimenti continui ed esercitazioni pratiche sotto forma di problemi. Quest’ultima parte mi sembra fondamentale al fine di imparare SAS: il paragone più calzante è con l’imparare a suonare uno strumento, magari il pianoforte. Sicuramente è molto più difficile suonare il pianoforte che programmare in SAS, anche perchè SAS cerca di essere sempre più semplice da usare con il passare del tempo, mentre il pianoforte non è cambiato sostanzialmente negli ultimi decenni. Però chi impara a suonare il pianoforte si appoggia ad un insegnante che sfrutta secoli di esperienze di insegnamenti impartiti dal suo insegnante, da chi ha istruito il suo insegnante, ecc. Questo non è possibile per l’insegnamento di un linguaggio di programmazione, poichè fino a 50 r SAS° e r SAS/GRAPH° sono marchi registrati di SAS Institute Inc. 6 Introduzione anni fa non esistevano (in pratica) linguaggi di programmazione: la conseguenza è che insegnare a programmare è ancora un’arte che non ha regole prestabilite. Il paragone con il pianoforte porta a comprendere come l’esercizio continuo e controllato da parte dell’insegnante sia il modo migliore per imparare qualcosa di nuovo: in questo caso SAS. Per questo motivo troverete una serie di esercizi da svolgere: tutti questi esercizi vengono risolti nel modo preferito dall’autore, non si vuole escludere la possibilità di soluzioni alternative, semplicemente si vuole garantire ad ognuno di poter seguire uno stile coerente in tutto il testo. Chi utilizza il linguaggio Perl è abituato a sentire la frase “There’s More Than One Way To Do It” che è uno dei concetti simbolo di tale linguaggio. Questo permette una grande libertà e vantaggi indiscutibili per il programmatore esperto e fonte inesauribile di confusione per chi non ha ancora raggiunto una sufficiente esperienza. I fondamenti 2.1 i linguaggi di programmazione Una delle principali limitazioni dei calcolatori attuali è la loro incapacità di comprendere istruzioni impartite in un linguaggio naturale (siamo tutti talmente abituati a questo fatto da considerarlo inevitabile, in realtà un computer in grado di comprendere un linguaggio naturale permetterebbe di essere enormemente più produttivi). Pertanto diventa necessario ricorrere ad un linguaggio artificiale per impartire le istruzione al computer. In cambio di questo nostro adattamento al linguaggio da utilizzare, il computer ci ricompenserà con la sua capacità di effettuare calcoli con una velocità e affidabilità non possibili per gli esseri umani. In generale i linguaggi di programmazione devono soddisfare due esigenze contrastanti: essere sufficientemente vicini ad un linguaggio naturale, in modo da rendere più semplice scrivere un programma, ed essere sufficientemente vicini ad un codice eseguibile direttamente dal calcolatore. Per ovviare a questo problema sono stati introdotti i compilatori, ovvero programmi che si occupano di tradurre un programma scritto in uno specifico linguaggio di programmazione in codice eseguibile. Questo ha portato alla possibilità di utilizzare linguaggi di programmazione molto più vicini ad un linguaggio naturale di quanto non fosse possibile pochi decenni fa. Per fortuna SAS è un linguaggio di programmazione che cerca di essere il più possibile vicino ad un linguaggio naturale, ma comunque sarà necessario comprendere come comportarsi per sfruttare pienamente le potenzialità del linguaggio. Esistono almeno tre tipologie di linguaggi di programmazione: • i linguaggi imperativi, dove un programma consiste nelle istruzioni dettagliate su come completare un assegnamento. Rientrano in questa categoria C, C++, Basic, Pascal, Java e le ricette per la cucina. • i linguaggi dichiarativi, dove un programma è l’insieme di ciò che deve essere ottenuto. Esempi di questo tipo di linguaggi sono SQL e gli ordini (“Leggi questo libro e scrivine un riassunto”). • i linguaggi funzionali, dove un programma viene visto come funzione che ha per argomento un insieme di dati e restituisce il risultato voluto. Esempi di linguaggi funzionali sono Lisp e Scheme. Il vantaggio dei linguaggi dichiarativi rispetto a quelli imperativi è che i programmi sono molto più sintetici e semplici da comprendere e modificare. Lo svantaggio consiste nel fatto che l’interprete del programma deve essere notevolmente più complesso, in quanto deve sapere come effettuare i compiti richiesti (ad esempio, riferendosi all’esempio fatto in precedenza, deve sapere leggere un libro, estrarre le informazioni ivi contenute e sintetizzarle efficacemente). SAS è sostanzialmente un linguaggio in parte imperativo ed in parte dichiarativo, ad esempio l’interprete sa come calcolare numerose statistiche di un insieme di valori, ma il programmatore deve occuparsi di indicare esplicitamente su quali valori devono essere calcolate le statistiche. Come vedremo in 8 I fondamenti VERO FALSO Condizione Istruzione 1 Istruzione 2 Figura 2.1: Schema di istruzione condizionale seguito le componenti dichiarative sono particolarmente potenti e semplici da utilizzare, maggiore difficoltà presentano la parti imperative. 2.2 istruzioni condizionali Una caratteristica della quasi totalità dei risultati che possiamo volere ottenere è che non tutti i dati in ingresso devono essere trattati ugualmente: ad esempio siamo interessati soltanto alle filiali che hanno ottenuto almeno un fatturato di EUR 1000000. Questo tipo di distinzione viene efficacemente riassunta dalla Figura 2.1, dove Istruzione 1 viene eseguita se la condizione è verificata, ed esegue Istruzione 2 altrimenti. Diventa quindi possibili dividere una istruzione condizionale in più componenti come segue: 1. la condizione, ovvero un predicato logico che può assumere solo due valori, vero o falso; 2. una istruzione che permette di determinare quale istruzione deve essere eseguita immediatamente dopo la valutazione della condizione Tale istruzione è solitamente la if condizione then . . . else. La semantica di tale istruzione è: valuta la condizione, se tale condizione è vera allora esegui le istruzioni scritte subito dopo then, altrimenti esegui le istruzioni scritte subito dopo else. Il fulcro di tale costrutto è pertanto la condizione, per cui ci sembra necessario avere a disposizione uno strumento sufficientemente potente per esprimere condizioni almeno moderatamente complesse. La nozione di condizione permette di decidere quali istruzioni debbano essere eseguite. Più precisamente una condizione può assumere solo due valori, vero o falso. Alcuni operatori (detti operatori logici o booleani ) agiscono sulle condizioni: si tratta degli operatori not, and, or. Gli effetti di tali operatori sono mostrati nella Tabella 2.1. 2.3 Schema di ciclo produttivo x falso falso vero vero y falso vero falso vero NOT(x) x AND y vero falso vero falso falso falso falso vero 9 x OR y falso vero vero vero x NAND y vero vero vero falso Tabella 2.1: Semantica degli operatori booleani 2.3 schema di ciclo produttivo Sotto il nome di SAS intendiamo più componenti (o strumenti), integrati fra loro, per l’analisi statistica di dati. In particolare SAS è un sistema per l’analisi di dati che incorpora, fra le altre cose, un editor che permette di scrivere programmi SAS nel linguaggio SAS . Tale programma verrà poi interpretato ed eseguito dal sistema SAS. Tutte queste componenti sono integrate in quello che verrà chiamato d’ora in poi semplicemente SAS. L’obiettivo è la scrittura di un programma in grado di risolvere un problema: non esistono regole fisse e predeterminate, inoltre non è possibile scrivere un programma corretto senza prima riflettere adeguatamente sul problema da risolvere (il fatto che programmatori esperti siano in grado scrivere in tempi brevissimi un programma SAS corretto, non deve trarre in inganno chi si affaccia per la prima volta alla programmazione: ciò è possibile solo grazie alle funzionalità del linguaggio SAS che permette di descrivere con poche istruzioni programmi in grado di risolvere problemi non banali). Pertanto diventa di fondamentale importanza la fase di analisi del problema. Una delle tecniche più utilizzate per la progettazione è la cosiddetta top-down, dove il problema viene diviso in componenti distinte che sono collegate fra loro solo attraverso interfacce ben definite. Ogni progetto software si divide, almeno in prima approssimazione, in tre fasi: 1. Progettazione 2. Implementazione 3. Manutenzione Si è notato che è necessario affrontare con attenzione la fase di progettazione al fine di minimizzare il costo totale del progetto. Pertanto diventa necessario analizzare accuratamente il problema da risolvere prima di iniziare con l’implementazione vera e propria. 2.4 il sistema Una delle caratteristiche più importanti di SAS è che il sistema SAS è disponibile per svariati sistemi operativi e piattaforme hardware. Infatti SAS è nato come applicazione su mainframe, ma successivamente è stato portato prima su UNIX1 e su VMS, ed infine su Microsoft Windows2 . Pertanto SAS è disponibile su sistemi che variano dai 1 2 Nel 2001 UNIX è un copyright di Santa Cruz Operations (SCO), Inc. Microsoft Windows è un marchio registrato di Microsoft Corp., Inc. 10 I fondamenti Progetto Scrittura (editor) Test (esecuzione) Il programma è corretto? no sı̀ FINE Figura 2.2: Come si sviluppa un programma viene interpretato da Programma usato per scrivere Interprete Editor Sistema SAS Figura 2.3: Schema riassuntivo del sistema SAS 2.5 Sintassi basilare personal computer ai mainframe, inclusi vari minicomputer ed enterprise server quali r Hewlett-Packard°, r IBM° r ed altri. quelli prodotti da Sun Microsystems°, Per rendere possbile l’utilizzo industriale su tutte questi sistemi operativi, è stato necessario isolare tutte le componenti dipendenti dal sistema operativo dell’implementazione iniziale di SAS, al fine di slegare dal particolare ambiente di utilizzo tutte le funzionalità del linguaggio SAS. Ciò che varia sostanzialmente fra i vari sistemi operativi è l’ambiente (sia grafico che a caratteri) che è a disposizione dell’utente per scrivere i programmi SAS e introdurre i dati da analizzare. Comunque il linguaggio SAS è completamente indipendente dal sistema operativo: ciò ne rende ancora più semplice l’esposizione. Per quanto riguarda lo scopo di questo testo, è sufficiente notare che l’ambiente SAS consiste di alcune componenti fra loro collegate: • Il Program editor o l’enhanced editor : permette di introdurre, modificare ed eseguire un programma SAS. È consigliato prendere confidenza con l’uso del program editor, in quanto è la componente del sistema SAS che viene utilizzato per maggior tempo. In particolare è necessario capire come mandare in esecuzione un programma intero oppure solo una parte del programma, come salvare un programma SAS e l’utilizzo dei tasti funzione per muoversi fra le finestre e per richiamare il programma precedentemente mandato in esecuzione. • L’output contiene tutti i risultati in formato testuale di un programma SAS. • Le Finestre grafiche (sui sistemi che le supportano) contengono i risultati in formato grafico calcolati dal programma SAS. • Il Log contiene una copia annotata del programma eseguito. Più precisamente per ogni istruzione eseguita viene evidenziata ogni anomalia che si è venuta a verificare durante l’esecuzione. L’analisi del log è di gran lunga lo strumento più utile per individuare gli errori nei programmi SAS. • L’help contiene le informazioni riguardanti tutte le funzionalità presenti nella installazione di SAS a disposizione. Vista la vastità della documentazione presente, diventa improponibile avere una copia cartacea di tutte le informazioni presenti nell’help. Per le stesse ragioni è abbastanza frequente non ricordarsi la sintassi esatta di alcune funzioni che si vogliono utilizzare: l’help di SAS è fondamentale per superare questi problemi. Un’altra particolarità di SAS consiste nella sua suddivisione in moduli: infatti al cosiddetto modulo base (in cui si trovano tutte le funzionalità che tratteremo in questo testo) sono disponibili numerosi moduli che permettono di utilizzare nuove funzionalità avanzate. 2.5 sintassi basilare Un linguaggio di programmazione deve essere tradotto in maniera non ambigua in azioni che il computer deve svolgere: ciò fà sı̀ che non sia possibile utilizzare un linguaggio naturale come la lingua italiana o quella inglese, ma che sia necessario utilizzare un linguaggio molto più semplice. In particolare ogni istruzione SAS viene terminata dal simbolo di punto e virgola ;, con l’eccezione dei commenti. 11 12 I fondamenti I commenti sono l’istruzione più importante di ogni linguaggio di programmazione. Non è uno scherzo: un programma che non sia adeguatamente commentato diventa incomprensibile anche per l’autore, a maggior ragione per chi debba modificare un programma scritto da altri. Un commento inizia con la coppia di simboli /* e termina con la coppia di simboli */. Un esempio di commento è presente nel Programma 2.1. Programma 2.1: Esempio di commento 1 2 3 4 2.6 /* * Questo è un commento valido * */ il dataset Come già detto in precedenza SAS è stato studiato per effettuare analisi statistiche di dati, ma non abbiamo ancora detto che cosa intendiamo per dato. Definizione 2.6.1 (Dato). Un dato è un’unità atomica di informazione. Un numero telefonico, oppure un nome sono esempi di dati. Secondo la definizione che abbiamo appena introdotto i dati in un insieme potrebbero apparire completamente scorrelati fra loro, tuttavia questo insieme di dati potrebbe contenere informazioni non visibili immediatamente. Questo fatto, insieme con la vastità dei dati usualmente disponibile, comportano la necessità di affrontare un’analisi statistica dei dati con adeguati strumenti computazionali. Lo strumento computazionale che tratteremo sarà, come è immaginabile, SAS. Affinchè i dati siano trattabili con SAS essidevono essere memorizzati in un formato predeterminato: quello tabellare, dove ogni colonna è una categoria diversa. In Figura 2.6 si trovano alcuni dati demografici riguardanti le regioni italiane. Come si può notare i dati sono organizzati secondo una struttura rigida: ogni colonna corrisponde ad una categoria o variabile, per cui le colonne contengono dati omogenei. Analogamente ogni riga consiste in una osservazione, ovvero tutti i dati che riguardano una unità analizzata. In questo caso specifico ogni osservazione corrisponde ad una regione. È di fondamen- Definizione 2.6.2 (Dataset). Una tabella con dati organizzati su colonne (variabili) tale importanza e righe (osservazioni) viene detta dataset. notare che SAS Quando SAS esegue delle operazioni su un dataset, tale dataset viene visitato (ed opera sempre su i dati ivi contenuti vengono utilizzati) in un ordine ben preciso, ovvero: dataset 1. una osservazione alla volta, iniziando dalla prima e terminando con l’ultima (“riga dopo riga”); 2.7 Relazione fra dataset e filesystem Osservazione Osservazione Osservazione Osservazione Osservazione Osservazione Osservazione Osservazione Osservazione Osservazione Osservazione Osservazione Osservazione Osservazione Osservazione Osservazione Osservazione Osservazione Osservazione Osservazione 1→ 2→ 3→ 4→ 5→ 6→ 7→ 8→ 9→ 10 → 11 → 12 → 13 → 14 → 15 → 16 → 17 → 18 → 19 → 20 → Variabile 1 ↓ Regione Piemonte Valle d’Aosta Liguria Lombardia Trentino Alto Adige Veneto Friuli Venezia Giulia Emilia-Romagna Toscana Marche Umbria Lazio Abruzzo Molise Campania Puglia Basilicata Calabria Sicilia Sardegna 13 Variabile 2 Variabile 3 ↓ ↓ Abitanti Superficie 4290412 25399 115397 3262 1668078 5416 8831264 23856 886914 13618 4363157 18364 1193520 7846 3899170 22123 3510114 22992 1427666 9693 804054 8456 5031230 17203 1243690 10794 327893 4438 5589587 13595 3986430 19347 605940 9992 2037686 15080 4961383 25708 1637705 24090 Figura 2.4: Esempio di dataset: popolazione e superficie delle regioni italiane 2. ogni osservazione viene letta una variabile alla volta, iniziando dalla prima e terminando con l’ultima (ogni osservazione viene letta “da sinistra a destra”). Talvolta è molto utile sfruttare il fatto che ogni dataset viene visitato in questo ordine. 2.7 relazione fra dataset e filesystem Nella sezione precedente è stato evidenziato come i dati in SAS siano organizzati logicamente sotto forma di dataset, ma non è stato specificato come tali dataset siano memorizzati. Una prima osservazione è che non è ragionevole pensare che un dataset sia sempre presente interamente in memoria centrale (RAM), in quanto SAS viene utilizzato in ambienti industriali dove i dataset analizzati possono avere milioni di osservazioni per alcune decine di variabili, ad esempio si consideri un dataset contenenti tutti i dati di vendita di un supermercato. Pertanto diventa necessario salvare i dataset su disco (o altra unità di memorizzazione adatta) e questo è uno dei compiti che il sistema SAS svolge automaticamente a patto che venga specificato il nome con cui salvare il dataset (come specificare il nome sarà spiegato più avanti). Ogni dataset viene salvato in un formato proprietario di SAS, tipicamente in un file con estensione .SD2, che non può essere ispezionato manualmente. Conseguentemente un problema è quello di interfacciarsi con fonti di dati 14 I fondamenti preesistenti che tipicamente consistono in file testuali opportunamente formattati, che possono avere una qualunque estensione. Bisogna pertanto fare attenzione e distinguere il concetto di dataset, che è interno a SAS, dal concetto di dataset salvato su file (che a sua volta è un concetto tipico di SAS) dal file che contiene dati trasformabili in un dataset. Quest’ultimo concetto non è esclusivo di SAS: infatti spesso tali dati vengono generati o elaborati da altre applicazioni (nel caso di dati di un supermercato vengono generati dal programma di gestione del magazzino). 2.8 sas come linguaggio di programmazione Nella sezione precedente abbiamo introdotto il concetto di dataset, ma non abbiamo ancora detto come gestire tale dataset. In effetti SAS dispone di un linguaggio di programmazione (che chiameremo linguaggio SAS disegnato specificatamente per il trattamento di dataset. I costrutti del linguaggio SAS possono essere divisi in due (sotto-)linguaggi: • linguaggio per la manipolazione dei dati; • linguaggio per la estrazione di informazione dai dati. Il primo linguaggio comprenderà quindi tutte le istruzioni necessarie per creare, salvare e caricare un dataset, mentre il secondo linguaggio contiene le istruzioni necessarie, ad esempio, a calcolare la media dei valori contenuti in una variabile del dataset. 2.9 le librerie I dataset sono organizzati in librerie, che è un insieme di dataset. Normalmente è desiderabile potere salvare (e successivamente riutilizzare) i dataset su cui si sono effettuate alcune elaborazioni, anche se ciò non è vero per tutti i dataset. Per facilitare tale distinzione esiste una libreria particolare: la libreria WORK. Ogni dataset nella libreria WORK viene considerato temporaneo e quindi non viene salvato. I dataset temporanei vengono contrapposti a quelli permanenti , che sono quelli che appartengono ad una libreria diversa da WORK: i dataset permanenti vengono automaticamente salvati dopo ogni operazione. Una operazione fondamentale, spesso la prima di ogni programma, è quindi la scelta della libreria che viene utilizzata: tale operazione prende il nome di libref , e si realizza tramite la LIBNAME come riportato nel programma 2.2. Programma 2.2: Esempio di libref 1 LIBNAME libreria ’c:\Desktop’ Il comando LIBNAME richiede due argomenti: il primo è il nome che si desidera associare alla libreria, il secondo è la locazione nel filesystem della libreria. Quest’ultima è una delle rare occasioni in cui un programma SAS è dipendente dal sistema operativo su cui deve essere eseguito. 2.10 Operazioni fondamentali su dataset Osservazione: Anche se è possibile scrivere un’espressione che effettui la stessa operazione su diversi sistemi operativi, trattare tale espressione è fuori dallo scopo di questo libro. 2.10 operazioni fondamentali su dataset Le componenti di un programma SAS possono essere suddivise in due categorie: • I data step, dove il dataset viene costruito o modificato. I data step consistono di tutte le operazioni di modifica dei dati. • I proc step, costituiscono le istruzioni dove i dati vengono analizzati e dove le statistiche richieste vengono calcolate. In questa sezione ci dedicheremo alla descrizione dei data step. Come si può immaginare ogni data step inizia con la istruzione DATA, dove l’unico parametro è il nome del dataset su cui si va ad operare. Il programma 2.3 legge un dataset chiamato regioni, appartenente alla libreria libro che a sua volta si trova nella directory c:\Desktop. Utilizzeremo questa libreria per tutti gli esempi in questo libro. L’istruzione DATA fà sı̀ che il dataset su cui agire sia regioni2, mentre la successiva SET impone che regioni sia il dataset che fornisce i dati su cui lavorare (ma tale dataset viene soltanto letto, non si effettua nessuna operazione su regioni). L’istruzione RUN termina il data step e serve ad evitare eventuali ambiguità sulla suddivisione fra le varie sezioni del programma. Una nota esplicativa si rende necessaria: SAS è un linguaggio interpretato, ovvero al momento dell’esecuzione il sistema SAS si occupa di eseguire ogni singola istruzione del programma. Il sistema interpreta una RUN come la fine della procedura che stà attualmente leggendo, per passare alla fase di esecuzione vera e propria. Non è necessario scrivere una RUN qualora la fine di una procedura non sia ambigua, ovvero quando la fine di una procedura sia immediatamente seguita dall’inizio di un’altra procedura. Comunque la presenza di RUN permette di separare meglio le diverse componenti del programma e quindi è consigliabile utilizzarla sempre. Programma 2.3: Copiare un dataset 1 2 3 4 5 6 7 /* * Copia regioni -> regioni2 */ libname libro ’c:\Desktop’; data libro.regioni2; set libro.regioni; run; La prima operazione su un dataset è chiaramente la sua creazione. Poichè un dataset è un oggetto che gode di vita propria diventa fondamentale decidere un nome per tale dataset. La scelta del nome per una libreria, cosı̀ come per un dataset, deve 15 16 I fondamenti essere ispirata da criteri di semplicità e chiarezza: in altre parole è preferibile utilizzare nomi brevi ma esplicativi e non ambigui. Seguendo queste indicazioni libro e regioni sono scelte adeguate, mentre regioni2 o nomelungoesenzasenso sono opinabili. In realtà la SET può indicare più dataset (ma tutti con la stessa struttura): in tal caso l’operazione che si effettua è la fusione dei dataset, in quanto vengono copiate tutte le osservazioni presenti nei dataset di ingresso. 2.11 creare un dataset Non sempre è possibile lavorare su dati preesistenti, ma è necesario creare da zero il dataset. In questo caso le operazioni di cui dobbiamo occuparci sono: • scegliere la libreria di cui il dataset dovrà fare parte, e quindi individuare la locazione fisica del dataset • scegliere il nome del dataset Una volta effettuate queste due operazioni sarà SAS ad occuparsi di salvare i dati contenuti nel dataset quando necessario (ad esempio al termine dell’esecuzione del programma). Il problema successivo da risolvere è quello della memorizzazione di dati nel dataset. Chiaramente il dataset appena creato non contiene dati (come potrebbe essere altrimenti? Abbiamo soltanto specificato la libreria ed il nome del dataset.) pertanto diventa fondamentale avere un insieme di comandi che permettano l’inserimento di dati. In particolare due aspetti riguardanti i dati che dovranno essere rappresentati dal dataset devono essere trattati: la strutturazione del dataset in variabili e l’elenco delle osservazioni. L’elenco delle variabili, e il tipo di ogni variabile viene definito tramite la INPUT. Tale istruzione richiede come argomenti l’elenco dei nomi delle variabili, eventualmente seguite dal simbolo $ nel caso si tratti di variabili che devono contenere dati alfanumerici. Si presume quindi che una variabile sia destinata a memorizzare dati numerici, e si deve esplicitare quando questa assunzione non sia vera. L’elenco delle osservazioni viene determinato utilizzando l’apposita istruzione DATALINES a cui deve seguire l’elenco delle osservazioni, con ogni osservazione su una riga a sè stante. L’elenco delle osservazioni deve terminare con un punto e virgola. Ad esempio un programma per construire un dataset contenente nome. cognome, altezza e peso per un insieme di persone è presentato nel seguente programma. Siamo ora pronti per vedere un semplice problema che utilizzi le nozioni appena introdotte. Problema 1: inizializzazione. Scrivere un programma SAS che crei un dataset equivalente a quello rappresentato in Tabella 2.6. Il programma in grado di risolvere il problema sarà chiaramente molto simile a quello descritto in precedenza. 2.12 leggere e salvare un dataset L’esercizio svolto nella Sez. 2.11 ci permette alcune puntualizzazioni: i nomi di variabili non possono assolutamente essere scelti a caso, e diventa importante usare nomi descrittivi. Tale possibilità è stata facilitata nelle versioni recenti di SAS, portando la 2.12 Leggere e salvare un dataset Programma 2.4: Definizione e inizializzazione di un dataset 1 2 3 4 5 6 7 8 libname libro ’c:\Desktop’; data libro.persone; input nome $ cognome $ altezza peso; datalines; mario rossi 180 75 elena bianchi 168 55 ; run; Programma 2.5: Dataset regioni: inizializzazione 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 libname libro ’c:\Desktop’; data libro.regioni; input regione $ abitanti superfic; datalines; Piemonte 4290412 25399 Valle d’Aosta 115397 3262 Liguria 1668078 5416 Lombardia 8831264 23856 Trentino Alto Adige 886914 13618 Veneto 4363157 18364 Friuli Venezia Giulia 1193520 7846 Emilia-Romagna 3899170 22123 Toscana 3510114 22992 Marche 1427666 9693 Umbria 804054 8456 Lazio 5031230 17203 Abruzzo 1243690 10794 Molise 327893 4438 Campania 5589587 13595 Puglia 3986430 19347 Basilicata 605940 9992 Calabria 2037686 15080 Sicilia 4961383 25708 Sardegna 1637705 24090 ; run; lunghezza massima di un nome di variabile da 8 a 32 caratteri quindi superficie non era un nome valido per una variabile). I limiti della procedura presentata sono due: il formato è fissato a priori (dati se- 17 18 Ovvero si possono usare sia Excel che OpenOffice (o StarOffice) su diversi sistemi operativi I fondamenti parati da spazi) ed i dati sono memorizzati nel programma, invece che su disco fisso. Quest’ultimo è un problema particolarmente significativo, poichè i dati da gestire possono facilmente occupare troppo spazio perchè sia possibile memorizzarli nel programma (basti pensare ai dati storici di movimentazioni di conti correnti in un’agenzia bancaria). A tal fine è possibile utilizzare l’istruzione INFILE che richiede come argomento il file che contiene i dati da analizzare. Un formato particolarmente utilizzato per la memorizzazione e lo scambio di dati è il cosiddetto CSV (Comma-separated values) dove i dati vengono separati da virgole anzichè da spazi. Praticamente tutti i programmi per la gestione di fogli di calcolo possono esportare ed importare dati in questo formato, ciò lo rende un minimo comun denominatore per trattare dati indipendentemente dalla piattaforma software utilizzata. In realtà SAS fornisce un metodo che permette di utilizzare dati divisi da un carattere speciale, tramite la parola chiave DLM. Decidendo quale simbolo (compreso fra apici) debba delimitare i dati siamo in grado di leggere i dati in una vasto insieme di formati. Problema 2: Lettura formato CSV. Si legga il dataset delle regioni italiane dal file ’c:\Desktop\regioni’ nel formato CSV Programma 2.6: Dataset regioni: lettura formato CSV 1 2 3 4 5 Senza questa opzione i dati sarebbero stati cercati nella riga successiva libname libro ’c:\Desktop’; data libro.regioni; infile ’c:\Desktop\regioni’ dlm=’,’; input regione $ abitanti superfic; run; Una nuova opzione per la INFILE è MISSOVER. Questa opzione assume che i dati in ingresso siano sempre una osservazione per riga, nel caso in cui i dati su una riga non siano sufficienti per assegnare un valore ad ogni variabile, allora si assume che i dati che non sono presenti siano mancanti. Questa opzione è utile quando siamo in presenza di dati con non sono sempre con la stessa identica struttura, ma al tempo stesso non sono completamente privi di struttura. Un esempio lo si può vedere con il Problema 19 a pagina 51. Salvare un dataset in un file specificato è analogo a leggere lo stesso dataset: si tratta di specificare, tramite l’istruzione FILE il nome del file su cui scrivere, oppure specificare il nome della libreria di cui il dataset è parte. Problema 3: salvataggio in libreria. Si legga il dataset delle regioni italiane dal file ’c:\Desktop\regioni’ nel formato CSV e lo si memorizzi nel dataset “regionifinte” Problema 4: salvataggio in libreria. Si legga il dataset delle regioni italiane dal file ’c:\Desktop\regioni’ nel formato CSV e lo si memorizzi nel file “a:regionifinte”. 2.13 esportare un dataset Normalmente i dataset SAS vengono salvati in un formato riservato che permette di massimizzare la velocità di accesso ai dati. Uno svantaggio di tale formato consiste nel 2.13 Esportare un dataset Programma 2.7: Dataset regioni: salvataggio in libreria 1 2 3 4 5 6 libname libro ’c:\Desktop’; data libro.regionifinte; set libro.regioni; infile ’c:\Desktop\regioni’ dlm=’,’; input regione abitanti superfic; run; Programma 2.8: Dataset regioni: salvataggio in libreria 1 2 3 4 5 6 libname libro ’c:\Desktop’; data libro.regioni; file ’a:libro.regionifinte’; infile ’c:\Desktop\regioni’ dlm=’,’; input regione abitanti superfic; run; fatto che esso non è portabile su calcolatori diversi (o meglio, potrebbero esserci problemi se si cambia sistema operativo). Per avere un dataset in un formato indipendente dal sistema utilizzato è necessario esportare il dataset in formato ASCII. Le istruzioni per esportare un dataset sono speculari a quelle per importare: il file su cui salvare viene specificato con l’istruzione FILE, mentre l’elenco delle variabili da esportare, insieme con le opzioni che specificano il formato, vnegono specificate con l’istruzione PUT. Problema 5: salvataggio in libreria. Si legga il dataset delle regioni italiane dal file ’c:\Desktop\regioni’ nel formato CSV e lo si memorizzi, in formato ASCII con campi separati da spazi, nel file “a:regionifinte.txt”. Programma 2.9: Dataset regioni: salvataggio in libreria 1 2 3 4 5 6 7 libname libro ’c:\Desktop’; data libro.regioni; infile ’c:\Desktop\regioni’ dlm=’,’; file ’a:libro.regionifinte.txt’; input regione abitanti superfic; put regione abitanti superfic; run; 19 20 I fondamenti 2.14 creare e cancellare variabili Finora abbiamo visto come creare un dataset, come leggere e scrivere i dati ivi contenuti, ma non abbiamo ancora visto come sia possibile modificare i dati, possibilmente rendendo esplicita dell’informazione già presente nel dataset. Uno dei modi più semplici per ottenere questo risultato consiste nella creazione di una nuova variabile, il cui contenuto è ottenibile direttamente dal dataset originario. In SAS ciò corrisponde ad “assegnare” alla nuova variabile un operazione i cui argomenti sono altre variabili del dataset. A partire da questa sezione sfrutteremo una delle caratteristiche fondamentali dei data step: tutte le operazioni comprese in un data step vengono eseguite per ogni osservazione. Il seguente problema esemplifica la situazione, dove la riga 5 viene eseguita per ogni osservazione. Problema 6: calcolo densità abitativa. Dato il dataset delle regioni italiane, si aggiunga una variabile densità che memorizza il numero di abitanti per kilometro quadrato. Programma 2.10: Dataset regioni: calcolo densità abitativa 1 2 3 4 5 libname libro ’c:\Desktop’; data libro.regioni; set libro.regionicomplete; densita=abitanti/superfic; run; La riga 5 è quella importante: il simbolo = suddivide il nome della nuova variabile (a sinistra) dall’operazione che descrive come ottenere i dati da associare alla nuova variabile (dopo l’uguale). Analogamente è possibile rimuovere una variabile da un dataset, tramite l’operazione DROP che deve essere seguita dalla variabile (o dall’insieme di variabili) da cancellare. Tale istruzione deve apparire all’interno di un DATA step. Un’istruzione che può essere utilizzata in alternativa alla DROP è KEEP: in questo caso solo le variabili indicate dopo KEEP vengono tenute nel dataset, mentre tutte le altre vengono eliminate. 2.15 visualizzare un dataset Nelle sezioni precedente è stato mostrato come memorizzare dati in un dataset, oltre ad alcune operazioni sugli stessi. Non abbiamo ancora visto come visualizzare il contenuto di un dataset, anche solo al fine di controllare se i programmi scritti siano in effetti corretti, ovvero se il dataset che abbiamo appena letto sia effettivamente corrispondente con quello che ci aspettiamo. Siccome non si tratta di un’operazione di gestione dati come quelle viste finora, ma di un’operazione di estrazione informazioni, verrà implementata tramite un PROC. In particolare la procedura da invocare è la CONTENTS. L’invocazione della PROC CONTENTS permette di dichiarare alcune opzioni: in particolare l’opzione DATA specifica il dataset che deve essere visualizzato. 2.16 Variabili indicizzate Problema 7: stampa contenuto. Dato il dataset delle regioni italiane, si aggiunga una variabile densità che memorizza il numero di abitanti per kilometro quadrato e si controlli la correttezza del nuovo dataset. Programma 2.11: Dataset regioni: contents 1 2 3 4 5 6 7 libname libro ’c:\Desktop’; data regionic; set libro.regioni; densita=abitanti/superfic; run; proc contents data=regionic; run; Il risultato di PROC CONTENTS non consiste però nel contenuto del dataset, ma in un elenco di utili informazioni (fra cui il numero di osservazioni e di variabili) che ci permettono di capire se il dataset sia stato caricato correttamente. Se invece il risultato che si vuole ottenere è la stampa del contenuto del dataset la procedura da invocare è la PROC PRINT, come si può vedere nel Prog. 2.12. Programma 2.12: Dataset regioni: stampa contenuto 1 2 3 4 5 6 7 2.16 libname libro ’c:\Desktop’; data regionic; set libro.regioni; densita=abitanti/superfic; run; proc print data=regionic; run; variabili indicizzate È abbastanza frequente il caso di dovere gestire un dataset in cui alcune variabili contengono dati fortemente correlati fra loro. Come esempio gestiremo un registro del tipo utilizzato nelle scuole superiori, in cui vogliamo memorizzare le assenze ed i voti ottenuti. Problema 8: Registro scolastico. Si gestisca un dataset per un registro scolastico, in cui le variabili sono nome e cognome dello studente, presenza o assenza per ogni lezione (in totale 100 lezioni), e voti ottenuti (in totale 5 voti). In riferimento al Problema 8 diventa utile raggruppare le variabili per le presenze in quanto rappresentano informazioni analoghe. A tal fine esiste una sintassi particolare 21 22 I fondamenti al momento della definizione delle variabili che ci permette di definire 100 variabili i cui nomi sono registro1, registro2, . . . , registro100: si utilizza la scrittura registro1-registro100. Adesso siamo in grado di risolvere il problema. In realtà nella sezione 3.2 comprenderemo come la risoluzione reale del problema preveda alcune complicazioni ulteriori. In ogni caso il programma che segue permette di leggere i dati in ingresso. Programma 2.13: Registro scolastico: inserimento dati 1 2 3 4 5 6 7 libname libro ’c:\Desktop’; /* data libro.registro; input nome $ cognome $ (presenze1-presenze100) ($) */ proc contents data=libro.registro; run; voti1-voti5; Notare che, nel Prog. 2.13, le variabili presenze1-presenze100 sono state raggruppate fra parentesi tonde al fine di assegnare a tutte lo stesso tipo (alfanumerico). Conseguentemente anche il simbolo $ è stato posto fra parentesi tonde. 2.17 estrarre osservazioni da un dataset Una operazione complementare alla creazione di osservazioni è l’estrazione di osservazioni. Ciò consiste in una copia selettiva del dataset, ovvero si selezionano quali osservazione debbano essere copiate, chiaramente tramite una sequenza di DATA STEP. Ad esempio esplicitiamo nel Prog. 2.14 la distinzione effettuata nel Prog. 3.6 creando due dataset. Si noti che ogni costante non numerica debba essere compresa fra apici. La IF è una istruzione condizionale che, in questo caso, non presenta esplicitamente l’istruzione da eseguire se la condizione è vera oppure falsa. In questo caso si assume che se la condizione è falsa allora non si esegue nessuna istruzione, altrimenti si assegna l’osservazione al dataset specificata all’inizio del DATA step. Pertanto il risultato del Prog. 2.14 è la creazione di due dataset temporanei contenenti i dati distinti per sesso. Il valore di una variabile viene confrontato con una costante (oppure un’altra variabile) tramite gli operatori in Tabella 2.2. 2.18 istruzioni condizionali Come spiegato nella Sez. 2.17 la IF permette di eseguire alcune istruzioni solo se una determinata condizione sia verificata. Tale istruzione è possibile solo in un data step, e la sua forma completa è IF condizione THEN istruzione1 ELSE istruzione2, dove istruzione1 viene eseguita se e solo se la condizione è vera, mentre la istruzione2 viene eseguita se e solo se la condizione è falsa. Sia il blocco ELSE istruzione2 che quello THEN istruzione 1 possono essere omessi: nel primo caso è equivalente a ELSE “non fare 2.18 Istruzioni condizionali Programma 2.14: Dataset registro: partizionamento IF 1 2 3 4 5 6 7 8 9 10 11 12 13 libname libro ’c:\Desktop’; /* data libro.registro; input nome cognome mf presenze1-presenze10 voti1-voti5; */ data maschi; set libro.registro; if mf eq ’m’; run; data femmine; set libro.registro; if mf eq ’f’; run; Operatore Significato EQ Uguale LT Minore LE Minore o uguale GT Maggiore GE Maggiore o uguale NE Diverso Tabella 2.2: Operatori di confronto nulla”, nel secondo è equivalente a THEN “azione di default”, che normalmente consiste nell’inserire l’osservazione nel dataset. È da notare che sia istruzione1 che istruzione2 devono essere un’unica istruzione. Ciò nonostante talvolta è utile potere eseguire più istruzioni se la condizione è vera: in tal caso la sequenza di istruzioni devono essere comprese fra le parole riservate DO; e END:. 23 Ancora operazioni su dataset 3.1 introduzione Le operazioni che abbiamo visto finora permettono una gestione basilare di un dataset: tuttavia un uso reale di SAS necessita di una conoscenza più approfondita di tali strumenti, in particolare di quelli che permetto l’inserimento e la visualizzazione dei dati. Successivamente si passerà al calcolo delle principali statistiche riguardanti un dataset, per poi passare alla manipolazione di un dataset. 3.2 inserire i dati In precedenza abbiamo trattato degli inserimenti semplici: i dati erano sempre perfettamente strutturati. Quando abbiamo introdotto il Problema 8 non abbiamo considerato i seguenti casi: • un registro contiene annotazione solo delle assenze; • non tutti gli studenti hanno esattamente 5 voti. Entrambi i punti appena evidenziati nascono dal problema dei dati mancanti , ovvero che il dataset possa contenere delle “caselle” vuote, e che il fatto che un dato manchi ha un significato ben preciso (non mi sembra ragionevole che uno zero come voto sia uguale a non essere presenti il giorno del compito in classe). Vista l’importanza di tale concetto SAS fornisce un modo semplice per identificare un dato mancate: se il dato atteso era numerico lo si sostituisce con un punto “.”, altrimenti (nel caso di dati alfanumerici) viene sostituito con uno spazio. Assumendo pertanto che si segnala con la lettera “a” un’assenza il seguente programma permette di inserire un semplice registro (con solo 10 giorni per non appesantire il programma). Programma 3.1: Dataset registro: inizializzazione 1 2 3 4 5 libname libro ’c:\Desktop’; data libro.registro; infile ’c:\Desktop\registro’ dlm=’,’; input nome $ cognome $ (presenze1-presenze10) ($) run; Dove il file c:\Desktop\registro è del tipo: 1 2 Mario,Rossi,,,,,,a,a,,,,3,2,1,.,3 Luisa,Bianchi,,,,,,,,,,,5,4,5,5,4 voti1-presenze5; Finalmente si capisce a cosa serve SAS 26 Ancora operazioni su dataset Problema 9: DATALINES. Era possibile inserire i dati del registro in un programma SAS con l’istruzione DATALINES? In generale il dato mancante viene identificato sempre con un punto, eventualmente racchiuso tra apici se si tratta di dato alfanumerico. Tale rappresentazione torna utile quando si vuole gestire esplicitamente il dato mancante. Un metodo alternativo per leggere i dati è il cosiddetto modo per colonne: ovvero per ogni variabile si specifica quanti caratteri debbano occupare i dati ivi contenuti. Supponiamo di riservare 20 caratteri per nome e cognome: adesso possiamo inizializzare il dataset con il seguente programma: Programma 3.2: Dataset registro: inizializzazione su colonne 1 2 3 4 5 6 7 8 9 libname libro ’c:\Desktop’; data libro.registro; input nome $ 1-20 cognome $ 21-40 presenze1-presenze10 $ 41-50 voti1-voti5 51-55; datalines; Mario Rossi a a 321 3 Luisa Bianchi 54554 ; run; Quando si utilizza il formato colonnare, nel log viene presentato un righello che permette di controllare con facilità se ci sono stati errori nella definizione del formato dei dati in ingresso. Un metodo più generale e flessibile è quello dell’informat: ovvero si specifica esplicitamente il formato dei dati riferiti ad ogni variabile. Il nostro programma diventa pertanto il seguente: Programma 3.3: Dataset registro: inizializzazione con informat 1 2 3 4 5 6 7 8 9 10 libname libro ’c:\Desktop’; data libro.registro; informat nome $20. cognome $20.; informat (presenze1-presenze10 voti1-voti5) 1; input nome cognome presenze1-presenze10 voti1-voti5; datalines; Mario Rossi a a 321 3 Luisa Bianchi 54554 ; run; 3.3 Array 27 In questo caso i formati sono definiti con l’istruzione INFORMAT dove ogni variabile viene seguita dal formato, ovvero viene specificato se il dato sia numerico o alfanumerico ed il numero massimo di caratteri. Un punto segue il numero di caratteri se uno spazio (o un altro simbolo di separazione) separa i dati anche se non sono stati utilizzati tutti i caratteri a disposizione. Si noti inoltre come le parentesi possono raggruppare insiemi di variabili a cui associare lo stesso formato. Sia il modo colonnare che quello degli informat permettono di definire con precisione il formato dei dati da ricevere in ingresso, senza caratteri di separazione che potrebbero essere ambigui. Inoltre il problema dei dati mancanti viene risolto nella maniera più intuitiva possibile: non inserendo il dato! Una tipologia particolare di dati è quella composta dalle date, che vengono rappresentate internamente in un formato numerico, e per cui sono disponibili vari formati di lettura o scrittura. In particolare i formati più utilizzati sono: • DATE7. consiste nel formato di 2 cifre per il giorno, 3 lettere per il mese e 2 cifre per l’anno, ad esempio 10Apr02. • DATE9. consiste nel formato di 2 cifre per il giorno, 3 lettere per il mese e 4 cifre per l’anno, ad esempio 10Apr2002. • DDMMYY. consiste nel formato di 2 cifre per il giorno, 2 cifre per il mese e 2 cifre per l’anno, ad esempio 100402. • DDMMYYYY. consiste nel formato di 2 cifre per il giorno, 4 cifre per il mese e 4 cifre per l’anno, ad esempio 10042002. Il formato deve essere sempre specificato dopo il nome della variabile a cui si riferisce, in maniera analoga a quanto fatto con il simbolo $ per specificare che il formato di una variabile è alfanumerico. 3.3 array Alcune nuove variabili sono calcolabili solo attraverso un insieme di operazioni sulle variabili inizialmente previste nel dataset, come ad esempio avevamo già visto per calcolare la densità di ogni regione. In alcuni casi le operazioni per calcolare i valori da assegnare ad una variabile sono più complesse quali, ad esempio, operazioni semplici su un insieme vasto di variabili. Si consideri il seguente problema sul dataset riguardante il registro scolastico: Problema 10: Numero assenze. Stampare il numero di totale di assenze di ogni alunno. La particolarità del Problema 10 consiste nel fatto che l’informazione che interessa può essere ottenuta solo analizzando un insieme potenzialmente vasto di variabili nella stessa osservazione. Pertanto scrivere esplicitamente l’espressione aritmetica non è pratico, sebbene sia possibile. Per riuscire a risolvere in maniera soddisfacente il problema sono necessari alcuni nuovi concetti, il primo dei quali è quello di array. Definizione 3.3.1 (Array). Un array è una sequenza di variabili, dove ogni variabile è accessibile tramite un indice. Quanto tempo ci vuole per scrivere tutte e 100 le variabili coinvolte? 28 Ancora operazioni su dataset Una coppia <nome di variabile, valore di un indice> è l’unico modo per accedere alla singola variabile. Ad esempio in Fig. 3.1 si trova raffigurato un array voti composto da 5 elementi. voti[1] voti[2] voti[3] voti[4] voti[5] Figura 3.1: Array voti Chiaramente un array ha senso solo per raggruppare variabili destinate a contenere dati omologhi, in quanto associare significati diversi a valori diversi di un indice porterebbe ben presto a confusione. Però voti[1] non è un nome di variabile, in quanto contiene dei caratteri che non sono lettere o cifre, pertanto viene fornita una corrispondenza biunivoca fra l’elemento dell’array voti[i] e la variabile votii e quindi, nell’esempio specifico, l’elemento dell’array voti[1] corrisponde alla variabile voti1. In Fig. 3.2 il nome con cui è possibile accedere ad un elemento dell’array viene mostrato sopra l’elemento stesso, all’interno viene mostrato il contenuto dell’elemento. voti[1] voti[2] voti[3] voti[4] voti[5] voti1 voti2 voti3 voti4 voti5 Figura 3.2: Array voti e variabili associate In breve perchè introdurre il concetto di array? Perchè permette di trattare variabili omogenee cambiando solo un emph, portando ad una trattazione più compatta di alcune operazioni sui dataset. Per il momento si può pensare che la variabile voti1 sia assolutamente equivalente all’elemento voti[1]. In effetti tale equivalenza può essere resa esplicita nel programma al momento della creazione, tramite l’istruzione ARRAY registro[100]: la parola riservata ARRAY introduce la definizione dell’array, la cui dimensione (ovvero il numero di elementi contenuti nell’array) viene indicato fra parentesi quadre. Per utilizzare anche i voti ci sono due possibilità: introdurre un secondo array oppure modificare la dichiarazione precedente in modo che l’array contenga 105 elementi (ma questa seconda possibilità viene sconsigliata). Inoltre l’istruzione ARRAY prevede la possibilità di un argomento opzionale che (eventualmente) deve essere scritto dopo la dimensione dell’array: tale argomento consiste nelle variabili che verranno identificate con gli elementi dell’array (nel Prog. 3.4 tale possibilità viene utilizzata per l’array vot). P Ora si tratta di calcolare il numero totale di assenze che è uguale a 100 i=1 voti[i]. Tale espressione può essere calcolato tramite l’Algoritmo 3.1. Non dovrebbe essere difficile convincersi che il risultato dell’Algoritmo 3.1 sia esatP tamente 100 i=1 voti[i]. Aggiungere voti[i] a totale viene fatto con la semplice istruzione totale+voti[i], il resto viene realizzato tramite il ciclo DO. . . TO. . . END. In tale istruzione si individuano tre parametri: 3.4 Ordinare un dataset 29 Algoritmo 3.1: Ciclo for 1. totale ← 0 2. i ← 1 3. Aggiungi voti[i] a totale 4. Aggiungi 1 a i 5. Se i≤100 torna al punto 2 • Un assegnamento (fra DO e TO) di un valore iniziale, tale assegnamento è la prima istruzione a venire eseguita. La variabile soggetta all’assegnamento assume il ruolo di contatore. • Un valore finale, il corpo del ciclo viene eseguito se il contatore è compreso fra il valore iniziale e quello finale (estremi compresi). • Un corpo del ciclo, consiste delle istruzioni da ripetere. Nel nostro caso diventa necessario creare una nuova variabile per mantenere il numero totale di assenze: al momento della creazione tale variabile viene automaticamente inizializzata a 0. È necessario sfruttare una caratteristica già introdotta in precedenza dei DATA step: quando si specifica la sorgente di un dataset (tramite la SET) tutto quello che segue viene eseguito una volta per ogni osservazione. La conseguenza è che è necessario porre a zero la variabile che deve contenere il numore di assenze, in tal modo si memorizzano le assenze di ogni studente. Una osservazione diventa fondamentale: ogni modifica apportata al dataset è persistente, ovvero continua ad avere effetto per tutta la durata dell’esecuzione del sistema SAS. Problema 11: Uso dei contatori. Cosa sarebbe successo se non ci fosse l’istruzione 7 nel Prog. 3.4? Le linee 8–10 del Prog. 3.4 sono la parte innovativa che ci permette di risolvere il Problema 10. La riga 8 significa che per ogni valore intero di i compreso fra 1 e 10 bisogna eseguire tutte le istruzioni fino alla parola chiave end. L’istruzione alla riga 9 dice di incrementare di uno tassenze (che è inizializzata a zero implicitamente). 3.4 ordinare un dataset Un’operazione fondamentale è l’ordinamento di dataset secondo i valori contenuti in una variabile. La procedura che permette di effettuare tale ordinamento è la PROC SORT. Analizzeremo come risolvere il Problema 12 come esempio. Problema 12: stampe ordinate. Dato il dataset in Tabella 2.6, stampare il dataset due volte: la prima volta in ordine alfabetico, la seconda volta in ordine decrescente di densità. 30 Ancora operazioni su dataset Programma 3.4: Dataset registro: evidenzazione assenze 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 libname libro ’c:\Desktop’; /* data libro.registro; input nome $ cognome $ mf $ (prese1-prese100) ($) voti1-voti5; */ data pres; set registro; tassenze=0; array prese[100]; array vot[5] voti1-voti5; do i=1 to 100; if presenze[i] eq ’a’ then tassenze+1; end; drop voti1-voti5 prese1-prese100 i; run; proc print data=pres; run; Programma 3.5: Dataset regioni: stampe ordinate 1 2 3 4 5 6 7 8 libname libro ’c:\Desktop’; data regionic; set libro.regioni; /* input regione abitanti superfic; */ densita=abitanti/superfic; run; 9 10 11 12 proc sort data=regionic; by regione; run; 13 14 15 16 proc sort data=regionic; by descending densita; run; La clausola BY all’interno della PROC SORT specifica quale variabile utilizzare per l’ordinamento e se tale ordinamento deve essere crescente (ASCENDING) o decrescente (DESCENDING). Inoltre è possibile indicare più variabile: in questo caso la seconda 3.5 Raggruppare osservazioni in un dataset 31 variabile viene utilizzata per ordinare le osservazioni che hanno stesso valore della prima variabile. 3.5 raggruppare osservazioni in un dataset Talvolta diventa importante suddividere un dataset in più sottodataset (più formalmante partizionare l’insieme delle osservazioni di un dataset in classi). Ad esempio riprendiamo il dataset del registro scolastico, ed assumiamo di avere una nuova variabile, chiamata mf, che indica se l’osservazione si riferisce ad un alunno oppure ad un’alunna. Siamo interessati ad analizzare separatamente i ragazzi dalle ragazze, ovvero vogliamo partizionare opportunamente l’insieme delle osservazioni. Questo obiettivo può essere ottenuto in SAS tramite due istruzioni distinte: BY e CLASS. La più semplice da utilizzare è CLASS che viene specificata come una clausola all’interno della procedura che deve utilizzare il partizionamento. Pertanto il Programma 3.6 calcola il numero di alunni per ogni sesso. Programma 3.6: Dataset registro: partizionamento con CLASS 1 2 3 4 5 6 7 8 9 libname libro ’c:\Desktop’; /* data libro.registro; input nome cognome mf presenze1-presenze10 voti1-voti5; */ proc means data=libro.registro n; title ’’Registro studenti’’; class mf; run; Usare BY è lievemente più complesso: infatti è necessario prima ordinare il dataset rispetto alla variabile in base a cui si vuole effettuare il partizionamento. La diversità fra CLASS e BY è giustificata dai diversi obiettivi che si vogliono ottenere: infatti BY sfrutta il fatto di operare su un dataset ordinato per utilizzare un algoritmo più veloce di quello implementato nel caso della CLASS che non può sfruttare tale proprietà ed è pertanto notevolmente più lento. Un programma funzionalmente equivalente al Prog. 3.6 è il Prog. 3.7 La differenza in termini di tempo e spazio sono giustificate dai diversi algoritmi utilizzati: la BY sfrutta il fatto che il dataset è già ordinato rispetto alla variabile di interesse, pertanto è sufficiente leggere in sequenza le osservazioni del dataset. Nel caso della CLASS sono necessarie 2 letture e contemporaneamente mantenere una struttura dati apposita per memorizzare le posizioni delle osservazioni relative ad ogni valore della variabile utilizzata. La differenza di tempo di esecuzione è apprezzabile solo per dataset particolarmente voluminosi 32 Ancora operazioni su dataset Programma 3.7: Dataset registro: partizionamento con BY 1 2 3 4 5 6 7 8 9 10 11 12 3.6 libname libro ’c:\Desktop’; /* data libro.registro; input nome cognome mf presenze1-presenze10 voti1-voti5; */ proc sort data=libro.registro; by mf; run; proc means data=libro.registro n; title ’’Registro studenti’’; by mf; run; ristrutturare dataset Talvolta è necessario modificare radicalmente la struttura (ovvero l’insieme di variabili) di un dataset, questa necessità è più probabile quando ogni osservazione contiene un numero variabile di dati. Riprendiamo pertanto il dataset del registro scolastico: siccome il numero di assenze è notevolmente minore di quello delle presenze, potremmo ristrutturare la parte del dataset che codifica le assenze in modo che ogni osservazione contenga lo studente e la data dell’assenza (pertanto ogni studente appare in tante osservazioni quante sono le assenze). A tal fine viene introdotta l’istruzione OUTPUT, il cui effetto è aggiungere esplicitamente una nuova osservazione in un dataset. Programma 3.8: Esempio di commento 1 2 3 4 5 6 7 8 data nuovo; set vecchio; array presenze[10]; do lezione=1 to 10; keep nome cognome lezione; if presenze[lezione]=’a’ then output; end; run; Nel caso del Prog 3.8 l’istruzione OUTPUT permette di aggiungere i dati relativi alle tre variabili nome, cognome, lezione nel dataset nuovo. Si noti inoltre l’istruzione KEEP immediatamente prima della OUTPUT che garantisce la determinazione dell’insieme delle variabili che vengono inserite nel dataset. La sintassi completa della OUTPUT è OUTPUT OUT=dataset che corrisponde ad inserire un’osservazione nel dataset dataset, 3.7 Stampare i dati 33 se la OUT viene omessa il dataset in cui viene fatto l’inserimento è quello di default: essendo all’interno di un data step l’unico dataset ragionevole è quello specificato nella DATA. Ogni volta che si utilizza la OUTPUT bisogna tenere presente che ogni dataset contiene sempre le stesse variabili, pertanto talvolta diventa necessario introdurre una variabile ausiliaria che verrà salvata nel nuovo dataset. Per ogni osservazione del dataset di ingresso ogni eventuale array viene inizializzato, ovvero ogni suo elemento viene posto uguale ad un missing value. Talvolta è invece necessario utilizzare il valore calcolato durante l’osservazione precedente, ad esempio quando si desidera ristrutturare un dataset in modo che si generi una sola nuova osservazione per un insieme di osservazioni del dataset originario. A tal fine si utilizza l’istruzione RETAIN dove si specifica un insieme di variabili (che sono associate ad un array) che non devono essere inizializzati per ogni osservazione. Per una applicazione della RETAIN si rimanda al Prob. ??. 3.7 stampare i dati Possiamo ora dedicarci a comprendere come sia possibile visualizzare i dati contenuti in un dataset in maniera da rendere più efficace la comunicazione con chi debba leggere l’output del programma. Questo compito viene effettuato con la PROC PRINT, al cui interno possono essere specificati: • un titolo da stampare su ogni pagina di output; • quale variabile scrivere nella prima colonna, se tale variabile non viene specificata si utilizza una variabile fittizia OBS dove viene mostrato un numero progressivo di osservazioni; • le variabili da visualizzare Problema 13: ID. Stampare il registro scolastico, dove in prima colonna si trovano i cognomi degli alunni e solo con i voti Programma 3.9: Dataset registro: stampa 1 2 3 4 5 6 7 8 9 10 libname libro ’c:\Desktop’; /* data libro.registro; input nome cognome presenze1-presenze10 voti1-voti5; */ proc print data=libro.registro; title ’’Registro studenti’’; id cognome; var nome voti1-voti5; run; Nel Programma 3.9 è possibile notare tre nuovi costrutti che permettono di risolvere il Problema 13: 34 Ancora operazioni su dataset • TITLE permette di stampare un titolo su ogni pagina di output. Tale titolo deve essere racchiuso fra doppi apici. • ID permette di scegliere quale variabile debba essere sostituita a OBS • VAR permette di specificare le variabili da stampare. L’output del Programma 3.9 è comunque comprensibile solo dalla persona che ha effettivamente scritto il programma, in quanto le intestazioni di ogni tabella sono i nomi delle variabili utilizzate. Sarebbe molto più utile avere delle descrizioni maggiormente dettagliate e, soprattutto, non soggiacenti alle limitazioni dei nomi di variabili (ad esempio fino alla versione 6.12, SAS accettava solo nomi di variabili composti da al più 8 caratteri). In nostro aiuto arriva l’istruzione LABEL che permette di associare una descrizione ad ogni variabile. Tale istruzione viene posta all’interno del DATA step ed ha un formato del tipo mostrato nel Prog. 3.10. Programma 3.10: descrizioni colonne 1 2 3 label presenze1 = "presenza giorno 12/1" presenze2 = "presenza giorno 13/1"; Si noti che l’istruzione LABEL permette di identificare un insieme di etichette, cosı̀ come una singola DATALINES permette di identificare i dati di un insieme di osservazioni. Il formato dei dati che si vogliono visualizzare potrebbe essere diverso da quello che si desidera effettivamente stampare: ad esempio potremmo essere interessati a mostrare la valuta in cui un importo viene espresso, oppure limitare il numero di cifre decimali. A tal fine si utilizza la direttiva FORMAT all’interno della PROC PRINT. La FORMAT viene seguita dalla coppia nome variabile, formato dove il formato può essere una variazione dei seguenti esempi: • DDMMYY6. per scrivere una data nel formato ggmmaa; • DOLLAR8 per scrivere un importo in dollari con 8 cifre totali; • 4 per scrivere un numero con 4 cifre totali. 3.8 riepilogo In questa sezione vengono riassunti alcuni concetti fondamentali da ricordare per gestire correttamente i dati in SAS: 1. SAS gestisce dati organizzati in dataset 2. i dataset sono organizzati in librerie 3. i dataset si dividono in temporanei o permanenti 3.8 Riepilogo 4. un file di dati puó essere importato in dataset tramite la INFILE 5. un dataset puó essere esportato in un file (esterno) tramite la INFILE 6. un dataset completo di dati (osservazioni) può essere creato tramite la DATALINES 7. per leggere o scrivere un dataset permanente è sufficiente (e necessario) specificare unicamente la libreria a cui appartiene 8. la input specifica l’insieme delle variabili che compongono un dataset. Non deve essere utilizzata se il dataset è stato precedentemente creato. 35 Calcolare delle statistiche Questa sezione è dedicata a quella che è la procedura più importante di tutto SAS: la PROC MEANS. Tale procedura permette di calcolare varie statistiche sulle osservazioni nel dataset. Cosı̀ come per gli altri casi di PROC visti in predenza immediatamente dopo la PROC MEANS si indica il dataset su cui calcolare le statistiche, questa volta seguono le statistiche che effettivamente si vogliono calcolare. Tali statistiche possono essere calcolate per un insieme di variabili: tale insieme viene indicato, analogamente alla PROC PRINT, tramite la direttiva VAR. Il Programma 4.1 calcola il numero di regioni nel dataset, la densità media e la deviazione standard della densità. Programma 4.1: Dataset regioni: statistiche sulla densità abitativa 1 2 3 4 5 6 7 8 9 10 11 12 libname libro ’c:\Desktop’; data regionic; set libro.regioni; /* input regione abitanti superfic; */ densita=abitanti/superfic; run; proc means data=regionic n mean std; title "statistiche sulla densita’"; var densita; run; Le più importanti statistiche che possono essere calcolare tramite la PROC MEANS sono mostrate nella Tabella 4.1. Una utile direttiva è MAXDEC: come è facile intuire permette di fissare il numero massimo di cifre decimali (dopo la virgola) che verranno visualizzate per ogni statistica indicata. Ad esempio per avere al più 2 cifre decimali nelle statistiche del Programma 4.1 la riga 6 dovrebbe essere sostituita con: proc means data=libro.regioni maxdec=2 n mean std; 4.1 estrazione di osservazioni significative L’utilizzo di BY può avere implicazioni estremamente importanti: ad esempio si consideri il Prog. 4.2, dove un dataset viene ordinato e poi copiato, specificando nell’istruzione BY la variabile utilizzata per ordinare. 38 Calcolare delle statistiche Direttiva Significato N il numero di osservazioni MEAN la media aritmetica STD la deviazione standard MAX il valore massimo MIN il valore minimo VAR la varianza SUM la somma dei valori SKEWNESS la skewness KURTOSIS la curtosi NMISS il numero di osservazioni con valori mancanti Tabella 4.1: Statistiche calcolabili in PROC MEANS Come specificato in Sez. 3.5 la BY raggruppa le osservazioni di un dataset, dove ogni gruppo consiste esattamente delle osservazioni in cui la variabile specificata assume un medesimo valore. L’utilizzo di BY densita ha automaticamente generato due predicati FIRST.densita e LAST.densita che vengono valutati veri rispettivamente per la prima e l’ultima osservazione di ogni gruppo. Pertanto il Prog. 4.2 costruisce un dataset ordinati che contiene solo la regione di minima densità. Programma 4.2: Dataset regioni: estrazione osservazioni estreme 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 libname libro ’c:\Desktop’; data libro.regioni; set libro.regionicomplete; /* input regione abitanti superfic; */ densita=abitanti/superfic; run; proc sort data=libro.regioni; by densita; run; data ordinati; set libro.regioni; by densita; if first.densita; run; Problema 14: Analisi statistica. Si consideri il dataset in Tabella 4.2. Si scriva un programma in grado di: 1. Leggere i dati tramite DATALINES e salvarli in un dataset permanente; 2. Calcolare la media dei passeggeri trasportati; 4.2 Altre statistiche 39 Partenza Destinazione milano bologna milano bologna milano bologna milano bologna bologna milano bologna milano bologna milano bologna milano Data Numero Passeggeri 10Mar2002 2034 11Mar2002 2538 12Mar2002 2212 13Mar2002 1823 10Mar2002 2034 11Mar2002 2563 12Mar2002 2418 13Mar2002 2012 Tabella 4.2: Dataset traffico ferroviario 3. Calcolare la media dei passeggeri trasportati per ogni giorno 4.2 altre statistiche La PROC MEANS fornisce un insieme ridotto di statistiche su un dataset: altre statistiche vengono fornite dalla PROC UNIVARIATE, in ogni caso si tratta di statistiche basilari. La sintassi è analoga a quella della PROC MEANS, un elenco delle principali funzionalità fornite dalla PROC UNIVARIATE è visibile nella Tabella 4.3. Direttiva N MEAN MEDIAN STD MAX MIN VAR SUM SKEWNESS KURTOSIS RANGE NMISS Significato il numero di osservazioni valide la media aritmetica la mediana la deviazione standard il valore massimo il valore miniimo la varianza la somma dei valori la skewness la curtosi l’intervallo dei valori assunti il numero di osservazioni con valori mancanti Tabella 4.3: Statistiche calcolabili in PROC MEANS 4.3 creare un dataset con le statistiche Un nuovo utilizzo della PROC MEANS consiste nella creazione di un dataset che contenga le statistiche cosı̀ calcolate. Questo richiede l’utilizzo di tre nuove parole riservate di SAS: • NOPRINT è una opzione della PROC MEANS che deve essere specificata dopo il dataset su cui operare. Il significato di questa opzione è che la procedura non deve essere creare output. 40 Calcolare delle statistiche • NWAY è una opzione della PROC MEANS che deve essere specificata dopo il dataset su cui operare. Nel caso in cui ci sia una CLASS o una BY nella procedura, permette di emettere solo le statistiche riguardante la stratificazione relativa a tutte le variabili specificate. Altrimenti verrebbero inseriti dei dati relativi ad una stratificazione parziale. • OUTPUT OUT=dataset permette di specificare (tramite la OUT) il dataset che deve essere creato. Ad esempio il Prog. 4.3 crea un dataset di nome stat che contiene le medie dei voti ottenute dai ragazzi e dalle ragazze. Programma 4.3: Dataset registro: creazione dataset riassuntivo 1 2 3 4 5 6 7 8 9 libname libro ’c:\Desktop’; /* data libro.registro; input nome cognome mf presenze1-presenze10 voti1-voti5; */ proc means data=libro.registro n noprint nway; output out=stat; class mf; run; Rappresentazioni grafiche In questo Capitolo tratteremo come rappresentare in formato grafico i dataset analizzati. 5.1 la proc plot Nelle funzionalità base fornite da SAS esiste la possibilità di ottenere alcune semplice semplici rappresentazioni “grafiche” dei dati. La parola grafiche è volutamente scritta fra virgolette, in quanto il grafico viene generato nella finestra di output ed utilizzando solo caratteri. In realtà si tratta di una rappresentazione molto approssimativa. Tali funzionalità sono comunque utili se ci si trova a lavorare su terminali alfanumerici (come quelli di un mainframe). La procedura che permette di ottenere tali rappresentazioni è la PROC PLOT. Problema 15: Grafico popolazione e superficie. Rappresentare graficamente la relazione fra popolazione e superficie di ogni regione. Il Problema 15 può essere risolto tramite una PROC PLOT come si può vedere nel Prog. 5.1. Programma 5.1: Dataset regioni: inizializzazione 1 2 3 4 5 6 7 8 libname libro ’c:\Desktop’; /* data libro.regioni; input regione $ abitanti superfic; */ proc plot data=libro.regioni; plot abitanti*superfic; run; La sintassi della PROC PLOT è analoga alle altre procedure che sono già state introdotte. Il grafico da rappresentare è definito tramite la parola riservata PLOT, dove ogni relazione da rappresentare viene individuata tramite la coppia delle due variabili (indipendente e dipendente) separate da un asterisco. Più relazioni possono essere raffigurate in uno stesso grafico, in tal caso le relazioni vengono separate da uno (o più) spazi, ma in questo caso è necessario: • specificare l’opzione OVERLAY, altrimenti ogni relazione viene rappresentata su un grafico separato; • specificare per ogni relazione quale simbolo (distinto) utilizzare per rappresentare i punti, altrimenti non è possibile distinguere le due relazioni. 42 Rappresentazioni grafiche Un semplice esempio di quanto appena esposto è ottenibile tramite il comando PLOT abitanti*superfic=’a’ densita*superfic=’b’ /overlay. 5.2 la proc gplot Una possibilità per avere grafici più raffinati consiste nella PROC GPLOT, però tale funzionalità è presente solo tramite il modulo SAS/GRAPH e non in SAS/BASE, pertanto viene introdutta dopo la PROC PLOT. Nel Prog. 5.2 risolviamo nuovamente il Prob. 15, dove si può notare che la sintassi è identica a quella della PROC PLOT. Programma 5.2: Dataset regioni: inizializzazione 1 2 3 4 5 6 7 8 5.3 libname libro ’c:\Desktop’; /* data libro.regioni; input regione $ abitanti superfic; */ proc gplot data=libro.regioni; plot abitanti*superfic; run; una migliore rappresentazione testuale Come abbiamo visto in precedenza spesso i dataset contengono dati in formato numerico o comunque in un formato abbastanza criptico da poter essere interpretato solo dalla persona che ha disegnato il dataset e il programma SAS. Questo è giustificato anche dal fatto che l’interprete SAS elabora in maniera più efficienti informazioni in formato numerico anzichè alfabetico (inoltre alcune stastiche hanno senso solo se i dati sono numerici). Questo è in contrapposizione con il fatto che alcune informazioni sono per loro natura alfabetica: si pensi ad esempio alla nazionalità di una persona, oppure il giudizio su un prodotto (pessimo, neutrale, buono). In questo caso diventa conveniente fornire una corrispondenza biunivoca fra i valori letterali e quelli numerici. Ciò viene realizzato tramite la PROC FORMAT, dove dei nuovi formati vengono definiti. Successivamente (tipicamente in un data step) viene dichiarato il formato di una variabile con l’istruzione FORMAT. Problema 16: Format. Consideriamo un dataset in cui l’unica variabile rappresenti un colore fra Rosso, Giallo e Blu, identificati rispettivamente dai valori numerici 0, 1 e 2. Stampare il dataset con i nomi dei colori. 5.3 Una migliore rappresentazione testuale Programma 5.3: Esempio di FORMAT 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 proc format; value $colore ’0’=’Rosso’ ’1’=’Giallo’ ’2’=’Blu’; run; data prog; input colore; datalines; 0 2 2 1 0 ; label colore=’Colore inserito’; format colore $colore; run; proc print data=colore; run; 43 Dai dati alle informazioni In questo capitolo ci occupiamo di estrarre informazioni utili dai dati. 6.1 analisi delle frequenze Una delle più semplici analisi statistiche che sono possibili su un dataset è l’analisi delle frequenze. Visto il ruolo basilare occupato da tale analisi, in SAS una procedura viene dedicata all’uopo: la PROC FREQ. La sintassi è quella standard dei PROC step in SAS, e l’output è il numero di occorrenze per ogni valore della variabile specificata. Problema 17: Analisi frequenze. Si consideri il dataset del registro. Effettuare un’analisi delle frequenze riguardante il numbero di assenze di ogni alunno La soluzione al Prob. 17 (visualizzata nel Prog. 6.1) sfrutta il Prog. 3.4 per calcolare il numero di assenze per ogni alunno. L’analisi delle frequenze richiede una semplice chiamata della PROC FREQ. Programma 6.1: Dataset registro: evidenzazione assenze 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 libname libro ’c:\Desktop’; /* data libro.registro; input nome $ cognome $ mf $ (prese1-prese10) ($) voti1-voti5; */ data pres; set registro; array presenze[10] prese1 - prese10; do i=1 to 10; if presenze[i] eq ’a’ then tassenze+1; end; run; proc freq data=pres; table tassenze; run; Analizzando più in dettaglio il Prog. 6.1 si può notare come la variabile su cui effettuare l’analisi delle frequenze viene indicata tramite la direttiva TABLES. 6.2 la proc corr Un tipo di informazione utile presente nei dati, ma che non sempre è facilmente individuabile è la cosidetta correlazione lineare che esprime quanto una variabile sia funzione lineare di una seconda variabile. 46 Dai dati alle informazioni In questo caso SAS permette di calcolare facilmente la correlazione lineare di ogni coppia di variabili presi in un determinato insieme. Un esempio esemplificativo della utilità di tale approccio è rintracciabile nel campo degli esami universitari. Studente Mario Rossi Giovanni Bianchi Laura Verdi Esame1 24 23 25 Esame2 Esame3 27 26 28 24 29 30 Esame4 24 23 30 Esame5 27 24 27 Esame6 26 25 29 Tabella 6.1: Esami sostenuti Nella Tabella 6.2 sono riportati i voti ottenuti da alcuni studenti per alcuni esami. Nella prima riga indichiamo i nomi delle variabili che utilizzeremo in SAS. L’obiettivo è determinare quali esami presentano delle votazioni maggiormente correlate fra loro. Programma 6.2: Dataset esami: correlazione voti 1 2 3 4 5 6 7 8 9 10 11 12 13 libname libro ’c:\Desktop’; /* data libro.esami; input nome $ cognome $ voti1-voti6; */ datalines; Mario Rossi 24 27 26 24 27 26 Giovanni Bianchi 23 28 24 23 24 25 Laura Verdi 25 29 30 30 27 29 run; proc corr data=libro.esami; var voti1-voti6; run; Il risultato del Programma 6.2 è un riassunto delle principali statistiche riguardanti il dataset e i dati riguardanti la correlazione di ogni coppia di esami. Siccome le variabili interessate sono 6 i risultati considerano 62 = 36 correlazioni, rendendo difficile identificare rapidamente quali variabili siano maggiormente collegate. Per limitare questo problema in SAS viene permesso di separare le variabili indipendenti da quelle dipendenti tramite la WITH: tale clausola permette di specificare le variabili dipendenti che, nel caso tale clausola non sia specificata, si intendo essere coincindenti con le variabili indipendenti specificate con VAR. Una opzione della PROC CORR è BEST che può essere posta uguale al numero di correlazioni che devono essere visualizzate per ogni variabile: chiaramente vengono visualizzate solo le correlazioni più significative. Ad esempio il Prog. 6.2 potrebbe essere modificato utilizzando l’istruzione proc corr data=libro.esami /best=2; per mostrare solo 2 correlazioni per variabile. 6.3 Tabelle a 2 entrate 6.3 tabelle a 2 entrate Una analisi delle frequenze più raffinata è quella della cosiddetta tabella a 2 entrate, dove vengono visualizzate le frequenze di una coppia di valori, una per ogni variabile. La sintassi è analoga a quella già spiegata della PROC FREQ, dove le due variabili interessate vengono divise dall’asterisco *. Un esempio viene mostrato nel Prog. 6.3. Programma 6.3: Dataset esami: tabella a 2 entrate 1 2 3 4 5 6 7 6.4 /* data libro.esami; input nome $ cognome $ voti1-voti6; */ proc freq data=libro.esami; tables voti1*voti2; run; analisi di regressione Assumiamo che due variabili contengano dati che sono in relazione rappresentabile con una retta (ovvero si assume che y = ax + b dove x e y sono rispettivamente la variabile indipendente e dipendente). In questo caso siamo interessati a trovare le due costanti a, b che meglio identificano la relazione: ciò viene abitualmente ottenuto con il metodo dei minimi quadrati che richiede il calcolo dei valori di a, b che minimizzano la funzione P 2 i (axi + b − yi ) dove xi , yi sono i valori delle variabili nel dataset. La procedura che permette di realizzare questo è la PROC REG. Problema 18: Regressione lineare. Supponiamo che esista una correlazione lineare fra il numero di assenze e la somma delle votazioni ottenute. Quale è la retta che identifica questa relazione? Nel Prog. 6.4 i cicli DO calcolano il numero totale di assenze e la somma dei voti, memorizzandoli rispettivamente nelle variabili tassenze e tvoti. All’interno della PROC REG l’istruzione MODEL specifica la relazione che si vuole determinare: in particolare la sintassi è MODEL y=x dove y è la variabile dipendente e x quella indipendente. Il risultato della PROC REG è abbastanza complesso e non completamente intuitivo: i due parametri b e a sono rispettivamente denominati INTERCEPT e con il nome della variabile indipendente indicata nella MODEL. 6.5 grafico di regressione Come spiegato nella Sez. 6.4 la PROC REG permette di individuare una retta che permette (sperabilmente) di approssimare i dati analizzati. Una rappresentazione grafica di tale fatto consiste nel rappresentare contemporaneamente (ovvero in un unico grafico) sia la retta che i dati analizzati. Ciò può essere ottenuto tramite una istruzione 47 48 Dai dati alle informazioni Programma 6.4: Dataset registro: relazione fra assenze e media voti 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 libname libro ’c:\Desktop’; /* data libro.registro; input nome $ cognome $ mf $ (prese1-prese10) ($) voti1-voti5; */ data pres; set registro; array presenze[10] prese1 - prese10; array votazion[10] voti1 - voti5; do i=1 to 10; if presenze[i] eq ’a’ then tassenze+1; end; do i=1 to 5; if votazion[i] eq ’a’ then tvoti+votazion[i]; end; run; proc reg data=pres; model tvoti=tassenze; run; PLOT all’interno della PROC REG. Nel Prog. 6.5 viene mostrato un programma derivato dal Prog. 6.4 per visualizzare tale grafico. 6.5 Grafico di regressione Programma 6.5: Dataset registro: relazione fra assenze e media voti 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 libname libro ’c:\Desktop’; /* data libro.registro; input nome $ cognome $ mf $ (prese1-prese10) ($) voti1-voti5; */ data pres; set registro; array presenze[10] prese1 - prese10; array votazion[10] voti1 - voti5; do i=1 to 10; if presenze[i] eq ’a’ then tassenze+1; end; do i=1 to 5; if votazion[i] eq ’a’ then tvoti+votazion[i]; end; run; proc reg data=pres; model tvoti=tassenze; plot predicted. *tassenze=’x’ tvoti*tassenze=’*’ /overlay; run; 49 Esercizi riepilogativi Gli esercizi in questo capitolo sono affrontabili già dopo avere letto (e compreso) la parte riguardante i data step, in quanto i vari obiettivi da realizzare sono chiaramente distinti e quindi dovrebbe essere semplice comprendere quali conoscenze siano richieste da ogni parte del problema. Problema 19: Analisi di osservazioni botaniche. Si consideri un dataset con il seguente insieme di variabili: n numero progressivo dell’osservazione. tr codice di controllo, è un intero fra 1 e 6. tree br codice alfanumerico del ramo a cui si riferisce l’osservazione. tl lunghezza del ramo in numero di misurazioni effettuate sul campione considerato inter valori delle misurazioni effettuate sul campione considerato, al massimo sono 29 misurazioni. Si scriva un programma SAS per calcolare: 1. per ogni osservazione, la media ed il massimo delle lunghezze fra i nodi; 2. la lunghezza media del ramo, suddivisa per trattamento; 3. la correlazione fra lunghezza del ramo, numero di misurazioni e tipo di trattamento; 4. per ogni albero, il numero di rami (branch) distinti considerati. Soluzioni degli esercizi Problema 9. Con le nozioni che erano state introdotte prima del testo del problema non era possibile inserire i dati all’interno del programma: infatti DLM è un’opzione di INFILE, ed i dati nel programma potevano essere separati solo da spazi. Per scrivere i dati mancanti è necessario l’utilizzo degli informat. Problema 11. In tassenze ci sarebbe il numero totale di assenze analizzate fino a quel momento, conseguentemente alla fine ci sarebbe stato il numero di assenze, sommato su tutti gli studenti. Problema 14. Il Prog. 8.1 risolve il problema. Programma 8.1: Dataset registro: relazione fra assenze e media voti 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 libname libro ’a:´ ; data libro.ferrovia; input partenza arrivo data date9. numpass; datalines; milano bologna 10Mar2002 2034 milano bologna 11Mar2002 2538 milano bologna 12Mar2002 2212 milano bologna 13Mar2002 1823 bologna milano 10Mar2002 2034 bologna milano 11Mar2002 2563 bologna milano 12Mar2002 2418 bologna milano 13Mar2002 2012 ; run; proc means data=libro.ferrovia mean; var numpass; run; proc means data=libro.ferrovia mean; class data; var numpass; run; Problema 19. Il Prog. 8 risolve il problema, dove si assume che i dati siano nel file dati.txt. 54 Soluzioni degli esercizi Programma 8.2: Soluzione del Prob.. 19 1 2 3 4 5 6 7 8 9 10 11 12 13 14 libname ’c:\Lezioni\es04’; data origine; infile ’c:\Lezioni\es04\dati.txt’ missover; input N TR TREE$ BR$ TL IN INTER1-INTER29; run: data divisi; set origine; array inter[29]; do i=1 to in; t=inter[i]; keep n t; output; end; run; 15 16 17 18 19 proc means data=divisi max mean; class n; var t; run; 20 21 22 23 24 proc means data=origine mean; class tr; var tl; run; 25 26 27 28 proc corr data=origine best=2; var tl in tr; run; 29 30 31 32 proc sort data=origine; by tree br; run; 33 34 35 36 37 38 39 40 41 data conta; set origine; by tree br; if first.tree then i=0; if first.br then i+1; if last.tree; keep tree br i; run; 42 43 44 proc print data=conta; run; Elenco dei problemi 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 inizializzazione . . . . . . . . . . Lettura formato CSV . . . . . . . salvataggio in libreria . . . . . . . salvataggio in libreria . . . . . . . salvataggio in libreria . . . . . . . calcolo densità abitativa . . . . . stampa contenuto . . . . . . . . . Registro scolastico . . . . . . . . DATALINES . . . . . . . . . . . Numero assenze . . . . . . . . . . Uso dei contatori . . . . . . . . . stampe ordinate . . . . . . . . . . ID . . . . . . . . . . . . . . . . . Analisi statistica . . . . . . . . . Grafico popolazione e superficie . Format . . . . . . . . . . . . . . . Analisi frequenze . . . . . . . . . Regressione lineare . . . . . . . . Analisi di osservazioni botaniche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 18 18 18 19 20 20 21 26 27 29 29 33 38 41 42 45 47 51 Elenco dei programmi 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 2.10 2.11 2.12 2.13 2.14 3.1 3.2 3.3 3.1 3.4 3.5 3.6 3.7 3.8 3.9 3.10 4.1 4.2 4.3 5.1 5.2 5.3 6.1 6.2 6.3 6.4 6.5 8.1 8.2 Esempio di commento . . . . . . . . . . . . . . . . Esempio di libref . . . . . . . . . . . . . . . . . . . Copiare un dataset . . . . . . . . . . . . . . . . . . Definizione e inizializzazione di un dataset . . . . . Dataset regioni: inizializzazione . . . . . . . . . . . Dataset regioni: lettura formato CSV . . . . . . . . Dataset regioni: salvataggio in libreria . . . . . . . Dataset regioni: salvataggio in libreria . . . . . . . Dataset regioni: salvataggio in libreria . . . . . . . Dataset regioni: calcolo densità abitativa . . . . . . Dataset regioni: contents . . . . . . . . . . . . . . . Dataset regioni: stampa contenuto . . . . . . . . . Registro scolastico: inserimento dati . . . . . . . . Dataset registro: partizionamento IF . . . . . . . . Dataset registro: inizializzazione . . . . . . . . . . . Dataset registro: inizializzazione su colonne . . . . Dataset registro: inizializzazione con informat . . . Ciclo for . . . . . . . . . . . . . . . . . . . . . . . . Dataset registro: evidenzazione assenze . . . . . . . Dataset regioni: stampe ordinate . . . . . . . . . . Dataset registro: partizionamento con CLASS . . . . Dataset registro: partizionamento con BY . . . . . . Esempio di commento . . . . . . . . . . . . . . . . Dataset registro: stampa . . . . . . . . . . . . . . . descrizioni colonne . . . . . . . . . . . . . . . . . . Dataset regioni: statistiche sulla densità abitativa . Dataset regioni: estrazione osservazioni estreme . . Dataset registro: creazione dataset riassuntivo . . . Dataset regioni: inizializzazione . . . . . . . . . . . Dataset regioni: inizializzazione . . . . . . . . . . . Esempio di FORMAT . . . . . . . . . . . . . . . . . . Dataset registro: evidenzazione assenze . . . . . . . Dataset esami: correlazione voti . . . . . . . . . . . Dataset esami: tabella a 2 entrate . . . . . . . . . . Dataset registro: relazione fra assenze e media voti Dataset registro: relazione fra assenze e media voti Dataset registro: relazione fra assenze e media voti Soluzione del Prob.. 19 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 14 15 17 17 18 19 19 19 20 21 21 22 23 25 26 26 29 30 30 31 32 32 33 34 37 38 40 41 42 43 45 46 47 48 49 53 54 Elenco delle figure 2.1 2.2 2.3 2.4 Schema di istruzione condizionale . . . . . . . . . . . . . Come si sviluppa un programma . . . . . . . . . . . . . Schema riassuntivo del sistema SAS . . . . . . . . . . . . Esempio di dataset: popolazione e superficie delle regioni . . . . . . . . . . . . . . . italiane . . . . . . . . . . . . . . . . . . . . 8 10 10 13 3.1 3.2 Array voti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Array voti e variabili associate . . . . . . . . . . . . . . . . . . . . . . . . 28 28 Indice analitico ARRAY, 28 array, 27 BT, 30 BY, 30, 35 ciclo, 28 CLASS, 30 DATA, 14 data step, 14 dataset, 12 dataset permanente, 14 dataset temporaneo, 14 dati mancanti, 25 dato, 12 do, 28 DROP, 19 editor, 11 FIRST, 36 FORMAT, 33, 40 graph, 11 print, 33 PROC CONTENTS, 20 CORR, 44 FORMAT, 40 FREQ, 43, 45 GPLOT, 39 MEANS, 35, 37 PLOT, 39 PRINT, 20, 32, 33, 35 REG, 45, 46 SORT, 29, 30 STEP, 20 UNIVARIATE, 37 proc step, 14 PROC MEANS, 36 programma, 9 RUN, 14 SET, 14 sistema, 9 help, 11 TABLE, 43 TITLE, 32 ID, 32 IF, 22, 23 VAR, 32, 35 variabile, 12 KEEP, 19 LABEL, 33 LAST, 36 LIBNAME, 14 libref, 14 libreria, 14 linguaggio, 9, 13 log, 11 MODEL, 46 obs, 32 osservazione, 12 output, 11 PLOT, 39 58 Licenza per Documentazione Libera GNU Versione 1.1, Marzo 2000 Copyright (C) 2000 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Chiunque può copiare e distribuire copie letterali di questo documento di licenza, ma non ne è permessa la modifica. 0. preambolo Lo scopo di questa licenza è di rendere un manuale, un testo o altri documenti scritti liberi nel senso di assicurare a tutti la libertà effettiva di copiarli e redistribuirli, con o senza modifiche, a fini di lucro o no. In secondo luogo questa licenza prevede per autori ed editori il modo per ottenere il giusto riconoscimento del proprio lavoro, preservandoli dall’essere considerati responsabili per modifiche apportate da altri. Questa licenza è un copyleft: ciò vuol dire che i lavori che derivano dal documento originale devono essere ugualmente liberi. è il complemento alla Licenza Pubblica Generale GNU, che è una licenza di tipo copyleft pensata per il software libero. Abbiamo progettato questa licenza al fine di applicarla alla documentazione del software libero, perché il software libero ha bisogno di documentazione libera: un programma libero dovrebbe accompagnarsi a manuali che forniscano la stessa libertà del software. Ma questa licenza non è limitata alla documentazione del software; può essere utilizzata per ogni testo che tratti un qualsiasi argomento e al di là dell’avvenuta pubblicazione cartacea. Raccomandiamo principalmente questa licenza per opere che abbiano fini didattici o per manuali di consultazione. 1. applicabilità e definizioni Questa licenza si applica a qualsiasi manuale o altra opera che contenga una nota messa dal detentore del copyright che dica che si può distribuire nei termini di questa licenza. Con Documento, in seguito ci si riferisce a qualsiasi manuale o opera. Ogni fruitore è un destinatario della licenza e viene indicato con voi. Una versione modificata di un documento è ogni opera contenente il documento stesso o parte di esso, sia riprodotto alla lettera che con modifiche, oppure traduzioni in un’altra lingua. Una sezione secondaria è un’appendice cui si fa riferimento o una premessa del documento e riguarda esclusivamente il rapporto dell’editore o dell’autore del documento con l’argomento generale del documento stesso (o argomenti affini) e non contiene nulla che possa essere compreso nell’argomento principale. (Per esempio, se il documento è in parte un manuale di matematica, una sezione secondaria non può contenere spiegazioni di matematica). Il rapporto con l’argomento può essere un tema collegato storicamente con il soggetto principale o con soggetti affini, o essere costituito da argomentazioni legali, commerciali, filosofiche, etiche o politiche pertinenti. Le sezioni non modificabili sono alcune sezioni secondarie i cui titoli sono esplicitamente 60 Licenza per Documentazione Libera GNU dichiarati essere sezioni non modificabili, nella nota che indica che il documento è realizzato sotto questa licenza. I testi copertina sono dei brevi brani di testo che sono elencati nella nota che indica che il documento è realizzato sotto questa licenza. Una copia trasparente del documento indica una copia leggibile da un calcolatore, codificata in un formato le cui specifiche sono disponibili pubblicamente, i cui contenuti possono essere visti e modificati direttamente, ora e in futuro, con generici editor di testi o (per immagini composte da pixel) con generici editor di immagini o (per i disegni) con qualche editor di disegni ampiamente diffuso, e la copia deve essere adatta al trattamento per la formattazione o per la conversione in una varietà di formati atti alla successiva formattazione. Una copia fatta in un altro formato di file trasparente il cui markup è stato progettato per intralciare o scoraggiare modifiche future da parte dei lettori non è trasparente. Una copia che non è trasparente è opaca. Esempi di formati adatti per copie trasparenti sono l’ASCII puro senza markup, il formato di input per Texinfo, il formato di input per LaTex, SGML o XML accoppiati ad una DTD pubblica e disponibile, e semplice HTML conforme agli standard e progettato per essere modificato manualmente. Formati opachi sono PostScript, PDF, formati proprietari che possono essere letti e modificati solo con word processor proprietari, SGML o XML per cui non è in genere disponibile la DTD o gli strumenti per il trattamento, e HTML generato automaticamente da qualche word processor per il solo output. La pagina del titolo di un libro stampato indica la pagina del titolo stessa, più qualche pagina seguente per quanto necessario a contenere in modo leggibile, il materiale che la licenza prevede che compaia nella pagina del titolo. Per opere in formati in cui non sia contemplata esplicitamente la pagina del titolo, con pagina del titolo si intende il testo prossimo al titolo dell’opera, precedente l’inizio del corpo del testo. 2. copie letterali Si può copiare e distribuire il documento con l’ausilio di qualsiasi mezzo, per fini di lucro e non, fornendo per tutte le copie questa licenza, le note sul copyright e l’avviso che questa licenza si applica al documento, e che non si aggiungono altre condizioni al di fuori di quelle della licenza stessa. Non si possono usare misure tecniche per impedire o controllare la lettura o la produzione di copie successive alle copie che si producono o distribuiscono. Però si possono ricavare compensi per le copie fornite. Se si distribuiscono un numero sufficiente di copie si devono seguire anche le condizioni della sezione 3. Si possono anche prestare copie e con le stesse condizioni sopra menzionate possono essere utilizzate in pubblico. 3. copiare in notevoli quantità Se si pubblicano a mezzo stampa più di 100 copie del documento, e la nota della licenza indica che esistono uno o più testi copertina, si devono includere nelle copie, in modo chiaro e leggibile, tutti i testi copertina indicati: il testo della prima di copertina in prima di copertina e il testo di quarta di copertina in quarta di copertina. Ambedue devono identificare l’editore che pubblica il documento. La prima di copertina deve presentare il titolo completo con tutte le parole che lo compongono egualmente visibili ed evidenti. Si può aggiungere altro materiale alle copertine. Il copiare con modifiche limitate alle sole copertine, purché si preservino il titolo e le altre condizioni viste in precedenza, è considerato alla stregua di copiare alla lettera. Se il testo richiesto per le copertine è troppo voluminoso per essere riprodotto in mo- Licenza per Documentazione Libera GNU do leggibile, se ne può mettere una prima parte per quanto ragionevolmente può stare in copertina, e continuare nelle pagine immediatamente seguenti. Se si pubblicano o distribuiscono copie opache del documento in numero superiore a 100, si deve anche includere una copia trasparente leggibile da un calcolatore per ogni copia o menzionare per ogni copia opaca un indirizzo di una rete di calcolatori pubblicamente accessibile in cui vi sia una copia trasparente completa del documento, spogliato di materiale aggiuntivo, e a cui si possa accedere anonimamente e gratuitamente per scaricare il documento usando i protocolli standard e pubblici generalmente usati. Se si adotta l’ultima opzione, si deve prestare la giusta attenzione, nel momento in cui si inizia la distribuzione in quantità elevata di copie opache, ad assicurarsi che la copia trasparente rimanga accessibile all’indirizzo stabilito fino ad almeno un anno di distanza dall’ultima distribuzione (direttamente o attraverso rivenditori) di quell’edizione al pubblico. è caldamente consigliato, benché non obbligatorio, contattare l’autore del documento prima di distribuirne un numero considerevole di copie, per metterlo in grado di fornire una versione aggiornata del documento. 4. modifiche Si possono copiare e distribuire versioni modificate del documento rispettando le condizioni delle precedenti sezioni 2 e 3, purché la versione modificata sia realizzata seguendo scrupolosamente questa stessa licenza, con la versione modificata che svolga il ruolo del documento, cosı̀ da estendere la licenza sulla distribuzione e la modifica a chiunque ne possieda una copia. Inoltre nelle versioni modificate si deve: • Usare nella pagina del titolo (e nelle copertine se ce ne sono) un titolo diverso da quello del documento, e da quelli di versioni precedenti (che devono essere elencati nella sezione storia del documento ove presenti). Si può usare lo stesso titolo di una versione precedente se l’editore di quella versione originale ne ha dato il permesso. • Elencare nella pagina del titolo, come autori, una o più persone o gruppi responsabili in qualità di autori delle modifiche nella versione modificata, insieme ad almeno cinque fra i principali autori del documento (tutti gli autori principali se sono meno di cinque). • Dichiarare nella pagina del titolo il nome dell’editore della versione modificata in qualità di editore. • Conservare tutte le note sul copyright del documento originale. • Aggiungere un’appropriata licenza per le modifiche di seguito alle altre licenze sui copyright. • Includere immediatamente dopo la nota di copyright, un avviso di licenza che dia pubblicamente il permesso di usare la versione modificata nei termini di questa licenza, nella forma mostrata nell’addendum alla fine di questo testo. • Preservare in questo avviso di licenza l’intera lista di sezioni non modificabili e testi copertina richieste come previsto dalla licenza del documento. • Includere una copia non modificata di questa licenza. • Conservare la sezione intitolata Storia, e il suo titolo, e aggiungere a questa un elemento che riporti al minimo il titolo, l’anno, i nuovi autori, e gli editori della versione modificata come figurano nella pagina del titolo. Se non ci sono sezioni intitolate Storia nel documento, createne una che riporti il titolo, gli autori, gli editori del documento 61 62 Licenza per Documentazione Libera GNU come figurano nella pagina del titolo, quindi aggiungete un elemento che descriva la versione modificata come detto in precedenza. • Conservare l’indirizzo in rete riportato nel documento, se c’è, al fine del pubblico accesso ad una copia trasparente, e possibilmente l’indirizzo in rete per le precedenti versioni su cui ci si è basati. Questi possono essere collocati nella sezione Storia. Si può omettere un indirizzo di rete per un’opera pubblicata almeno quattro anni prima del documento stesso, o se l’originario editore della versione cui ci si riferisce ne dà il permesso. • In ogni sezione di Ringraziamenti o Dediche, si conservino il titolo, il senso, il tono della sezione stessa. • Si conservino inalterate le sezioni non modificabili del documento, nei propri testi e nei propri titoli. I numeri della sezione o equivalenti non sono considerati parte del titolo della sezione. • Si cancelli ogni sezione intitolata Riconoscimenti. Solo questa sezione può non essere inclusa nella versione modificata. • Non si modifichi il titolo di sezioni esistenti come miglioria o per creare confusione con i titoli di sezioni non modificabili. Se la versione modificata comprende nuove sezioni di primaria importanza o appendici che ricadono in sezioni secondarie, e non contengono materiale copiato dal documento, si ha facoltà di rendere non modificabili quante sezioni si voglia. Per fare ciò si aggiunga il loro titolo alla lista delle sezioni immutabili nella nota di copyright della versione modificata. Questi titoli devono essere diversi dai titoli di ogni altra sezione. Si può aggiungere una sezione intitolata Riconoscimenti, a patto che non contenga altro che le approvazioni alla versione modificata prodotte da vari soggetti–per esempio, affermazioni di revisione o che il testo è stato approvato da una organizzazione come la definizione normativa di uno standard. Si può aggiungere un brano fino a cinque parole come Testo Copertina, e un brano fino a 25 parole come Testo di Retro Copertina, alla fine dell’elenco dei Testi Copertina nella versione modificata. Solamente un brano del Testo Copertina e uno del Testo di Retro Copertina possono essere aggiunti (anche con adattamenti) da ciascuna persona o organizzazione. Se il documento include già un testo copertina per la stessa copertina, precedentemente aggiunto o adattato da voi o dalla stessa organizzazione nel nome della quale si agisce, non se ne può aggiungere un altro, ma si può rimpiazzare il vecchio ottenendo l’esplicita autorizzazione dall’editore precedente che aveva aggiunto il testo copertina. L’autore/i e l’editore/i del documento non ottengono da questa licenza il permesso di usare i propri nomi per pubblicizzare la versione modificata o rivendicare l’approvazione di ogni versione modificata. 5. unione di documenti Si può unire il documento con altri realizzati sotto questa licenza, seguendo i termini definiti nella precedente sezione 4 per le versioni modificate, a patto che si includa l’insieme di tutte le Sezioni Invarianti di tutti i documenti originali, senza modifiche, e si elenchino tutte come Sezioni Invarianti della sintesi di documenti nella licenza della stessa. Nella sintesi è necessaria una sola copia di questa licenza, e multiple sezioni invarianti possono essere rimpiazzate da una singola copia se identiche. Se ci sono multiple Sezioni Invarianti con lo stesso nome ma contenuti differenti, si renda unico il titolo di ciascuna sezione aggiungendovi alla fine e fra parentesi, il nome dell’autore o editore della sezione, Licenza per Documentazione Libera GNU se noti, o altrimenti un numero distintivo. Si facciano gli stessi aggiustamenti ai titoli delle sezioni nell’elenco delle Sezioni Invarianti nella nota di copiright della sintesi. Nella sintesi si devono unire le varie sezioni intitolate storia nei vari documenti originali di partenza per formare una unica sezione intitolata storia; allo stesso modo si unisca ogni sezione intitolata Ringraziamenti, e ogni sezione intitolata Dediche. Si devono eliminare tutte le sezioni intitolate Riconoscimenti. 6. raccolte di documenti Si può produrre una raccolta che consista del documento e di altri realizzati sotto questa licenza; e rimpiazzare le singole copie di questa licenza nei vari documenti con una sola inclusa nella raccolta, solamente se si seguono le regole fissate da questa licenza per le copie alla lettera come se si applicassero a ciascun documento. Si può estrarre un singolo documento da una raccolta e distribuirlo individualmente sotto questa licenza, solo se si inserisce una copia di questa licenza nel documento estratto e se si seguono tutte le altre regole fissate da questa licenza per le copie alla lettera del documento. 7. raccogliere insieme a lavori indipendenti Una raccolta del documento o sue derivazioni con altri documenti o lavori separati o indipendenti, all’interno di o a formare un archivio o un supporto per la distribuzione, non è una versione modificata del documento nella sua interezza, se non ci sono copiright per l’intera raccolta. Ciascuna raccolta si chiama allora aggregato e questa licenza non si applica agli altri lavori contenuti in essa che ne sono parte, per il solo fatto di essere raccolti insieme, qualora non siano però loro stessi lavori derivati dal documento. Se le esigenze del Testo Copertina della sezione 3 sono applicabili a queste copie del documento allora, se il documento è inferiore ad un quarto dell’intero aggregato i Testi Copertina del documento possono essere piazzati in copertine che delimitano solo il documento all’interno dell’aggregato. Altrimenti devono apparire nella copertina dell’intero aggregato. 8. traduzioni La traduzione è considerata un tipo di modifica, e di conseguenza si possono distribuire traduzioni del documento seguendo i termini della sezione 4. Rimpiazzare sezioni non modificabili con traduzioni richiede un particolare permesso da parte dei detentori del diritto d’autore, ma si possono includere traduzioni di una o più sezioni non modificabili in aggiunta alle versioni originali di queste sezioni immutabili. Si può fornire una traduzione della presente licenza a patto che si includa anche l’originale versione inglese di questa licenza. In caso di discordanza fra la traduzione e l’originale inglese di questa licenza la versione originale inglese prevale sempre. 9. termini Non si può applicare un’altra licenza al documento, copiarlo, modificarlo, o distribuirlo al di fuori dei termini espressamente previsti da questa licenza. Ogni altro tentativo di applicare un’altra licenza al documento, copiarlo, modificarlo, o distribuirlo è deprecato e pone fine automaticamente ai diritti previsti da questa licenza. Comunque, per quanti abbiano ricevuto copie o abbiano diritti coperti da questa licenza, essi non ne cessano se si rimane perfettamente coerenti con quanto previsto dalla stessa. 63 64 Licenza per Documentazione Libera GNU 10. revisioni future di questa licenza La Free Software Foundation può pubblicare nuove, rivedute versioni della Licenza per Documentazione Libera GNU volta per volta. Qualche nuova versione potrebbe essere simile nello spirito alla versione attuale ma differire in dettagli per affrontare nuovi problemi e concetti. Si veda http://www.gnu.org/copyleft. Ad ogni versione della licenza viene dato un numero che distingue la versione stessa. Se il documento specifica che si riferisce ad una versione particolare della licenza contraddistinta dal numero o ogni versione successiva, si ha la possibilità di seguire termini e condizioni sia della versione specificata che di ogni versione successiva pubblicata (non come bozza) dalla Free Software Foundation. Se il documento non specifica un numero di versione particolare di questa licenza, si può scegliere ogni versione pubblicata (non come bozza) dalla Free Software Foundation.