...

Imparare - Facoltà di Scienze Statistiche

by user

on
Category: Documents
18

views

Report

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.
Fly UP