Espressioni¶
Diverse funzioni in pTabs (filter, select, rake, value_if, compute, ecc.)
richiedono o consentono l’utilizzo di espressioni sulle variabili del data frame.
E’ possibile specificare le espressioni in tre modi diversi:
il semplice nome della variabile o nome preceduto da ! per indicare i casi validi o non validi sulla variabile
un hash (dizionario) con le coppie variabile-valori. Più coppie variabile-valori sono unite in AND nell’espressione
una stringa con un’espressione composta da:
- Operatori aritmetici: +, -, *, /, %
- Operatori di confronto: <, >, <=, >=, <>, !=, =
- Operatori logici: AND, OR, NOT
- Selezione: CASE, IF
- Tutte le funzioni del modulo Math di Ruby, come SIN, COS, TAN, ecc.
- Le seguenti funzioni:
Funzione
Argomenti
Valore restituito
Descrizione
MAX
array
number
valore massimo
MIN
array
number
valore minimo
VALIDX
value, array
number
l’indice (a base 1) della prima occorrenza di value
VALIDXR
value, array
number
l’indice (a base 1) della prima occorrenza di value partendo da destra
VALIDX1
value, array
number
l’indice (a base 1) del’occorrenza di value se unico
MAXIDX
array
number
l’indice (a base 1) della prima occorrenza del valore massimo
MAXIDXR
array
number
l’indice (a base 1) della prima occorrenza del valore massimo partendo da destra
MAXIDX1
array
number
l’indice (a base 1) dell’occorrenza del valore massimo se unico
MINIDX
array
number
l’indice (a base 1) della prima occorrenza del valore minimo
MINIDXR
array
number
l’indice (a base 1) della prima occorrenza del valore minimo partendo da destra
MINIDX1
array
number
l’indice (a base 1) dell’occorrenza del valore minimo se unico
ROUND
number, ndec
number
arrotonda
ROUNDDOWN
number, ndec
number
arrotonda al numero inferiore
ROUNDUP
number, ndec
number
arrotonda al numero superiore
SUM
array
number
somma valori
MEAN
array
number
media valori
SDEV
array
number
deviazione standard valori
SUBT
value0, value1, value2, ...
number
sottrale al primo valore i successivi valori: value0 - value1 - value2...
DIFF
value1, value2
number
differenza due valori: value2 - value1
TRUNC
number
number
tronca i decimali
FLOAT
number
number
converte il numero in float
INT
number
number
converte il numero in intero
BETWEEN
value, min, max
boolean
testa se il valore è tra minimo e massimo; anche per date
EQ
value1, value2
boolean
testa se il primo valore è uguale al secondo; anche per date; i valori mancanti sono esclusi
NE
value1, value2
boolean
testa se il primo valore è diverso dal secondo; anche per date; i valori mancanti sono esclusi
GT
value1, value2
boolean
testa se il primo valore è maggiore del secondo; anche per date; i valori mancanti sono esclusi
LT
value1, value2
boolean
testa se il primo valore è minore del secondo; anche per date; i valori mancanti sono esclusi
GE
value1, value2
boolean
testa se il primo valore è maggiore o uguale al secondo; anche per date; i valori mancanti sono esclusi
LE
value1, value2
boolean
testa se il primo valore è minore o uguale al secondo; anche per date; i valori mancanti sono esclusi
MEQ
array
boolean
testa se i valori sono tutti uguali; i valori mancanti sono esclusi
MNE
array
boolean
testa se i valori sono tutti differenti; i valori mancanti sono esclusi
MGT
array
boolean
testa se il valore successivo è maggiore del precedente; i valori mancanti sono esclusi
MLT
array
boolean
testa se il valore successivo è minore o uguale al precedente; i valori mancanti sono esclusi
MGE
array
boolean
testa se il valore successivo è maggiore o uguale al precedente; i valori mancanti sono esclusi
MLE
array
boolean
testa se il valore successivo è minore o uguale al precedente; i valori mancanti sono esclusi
ISNUM
string
boolean
testa se il valore è un numero
TEXT
value
string
converte il numero in stringa
FIRST
array
il primo elemento valido dell’array
LAST
array
l’ultimo elemento valido dell’array
ANY
value, array
boolean
testa se almeno un elemento della lista è uguale al valore
MANY
VALUES(val1,val2,...), array
boolean
testa se almeno un elemento della lista è uguale a uno dei valori
IFANY
value, yes, no, array
testa se almeno un elemento della lista è uguale al valore e restituisce yes o no
ALL
value, array
boolean
testa se tutti gli elementi della lista sono uguali al valore
ALLVALID
value, array
boolean
testa se tutti gli elementi validi della lista sono uguali al valore
MALL
VALUES(val1,val2,...), array
boolean
testa se tutti gli elementi della lista sono uguali uno dei valori
IFALL
value, yes, no, array
testa se tutti gli elementi della lista sono uguali al valore e restituisce yes o no
NONE
value, array
boolean
testa se nesuno degli elementi della lista sono uguali al valore
MNONE
VALUES(val1,val2,...), array
boolean
testa se nesuno degli elementi della lista sono uguali a uno dei valori
IFNONE
value, yes, no, array
testa se nesuno degli elementi della lista sono uguali al valore e restituisce yes o no
VALID
array
boolean
testa se almeno un elemento è un valore valido
NVALID
array
number
restituisce il numero di elementi validi
BLANK
array
boolean
testa se nessun elemento è un valore valido
NBLANK
array
number
restituisce il numero di elementi non validi
COUNT
value, array
number
conta gli elementi uguali a valore
MCOUNT
VALUES(val1,val2,...), array
number
conta gli elementi uguali a uno dei valori
RECODE
value, VALUES(...), val, ...
number
ricodifica in nuovi valori
NUMBER
string
number
converte la stringa in numero
CONCAT
array
string
concatena le stringhe
STRIP
string
string
elimina gli spazi iniziali e finali dalla stringa
EMPTY
string
boolean
testa se la stringa è vuota
FILLED
string
boolean
testa se la stringa è piena
CAPITALIZE
string
string
converte il primo carattere della stringa in maiuscolo
TITLEIZE
string
string
converte il primo carattere di ogni parola in maiuscolo
UPCASE
string
string
converte la stringa in maiuscolo
DOWNCASE
string
string
converte la stringa in minuscolo
SCOUNT
string, text
number
conta le occorrenze di text in string
SPLIT
string, sep, ntoken
string
divide la stringa in base a sep
JOIN
array, sep
string
unisce le stringhe con sep
LPAD
string, number, text
string
giustifica la stringa a sinistra
RPAD
string, number, text
string
giustifica la stringa a destra
LEFT
string, number
string
restituisce i primi number caratteri
RIGHT
string, number
string
restituisce gli ultimi number caratteri
START
string
boolean
testa se la stringa inizia con i caratteri indicati
FINISH
string
boolean
testa se la stringa finisce con i caratteri indicati
CONTAIN
string
boolean
testa se la stringa contiene i caratteri indicati
MID
string, start, len
string
restituisce la sottostringa lunga len che parte dalla posizione start
LEN
string
number
string
SUBSTITUTE
string, search, repl
string
sostituisce search con repl
DATE
string
data
converte la stringa in data
YMD
year, month, day
data
converte anno, mese, giorno in data
DATETIME
string
datetime
converte la stringa in datetime
YMDHMS
year, month, day, hours, minutes, seconds
datetime
converte anno, mese, giorno, ore, minuti, secondi in datetime
YEAR
date|datetime|time
number
estrae l’anno da una data
MONTH
date|datetime|time
number
estrae il mese da una data
DAY
date|datetime|time
number
estrae il giorno da una data
WDAY
date|datetime|time
number
estrae il giorno della settimana da una data (1..7; 1=Lunedì, 7=Domenica)
YDAY
date|datetime|time
number
estrae l numero di giorni dell’anno da una data (1..366)
HOURS
datetime|time
number
estrae l’ora da una variabile datetime
MINUTES
datetime|time
number
estrae i minuti da una variabile datetime
SECONDS
datetime|time
number
estrae i secondi da una variabile datetime
DIFFYEARS
date0|datetime0, date1||datetime1
integer
il numero di anni completi trascorsi da date0 a date1
DIFFDAYS
date0|datetime0, date1||datetime1
integer
il numero di giorni completi trascorsi da date0 a date1
DIFFHH
date0|datetime0, date1||datetime1
integer
il numero di ore complete trascorse da date0 a date1
DIFFMM
date0|datetime0, date1||datetime1
integer
il numero di minuti completi trascorsi da date0 a date1
DIFFSS
date0|datetime0, date1||datetime1
integer
il numero di secondi trascorsi da date0 a date1
Solo in compute:
N
number
il numero totale di record
NROW
number
il numero progressivo del record (base 0)
RECNUM
number
il numero progressivo del record (base 1)
LAG
varname, n
ritorna il valore della variabile n record precedenti (se n è negativo) o n record successivi (se n è positivo) (default -1, il record precedente)
LABEL
varname
string
l’etichetta della variabile
LEVEL
varname, code
string
l’etichetta del livello della variabile
- Funzioni helper:
Variabile
Descrizione
VALUES
utilizzata per generare le liste dei valori nelle funzioni MANY, MALL, MNONE, MCOUNT: VALUES(1,2,3) equivale a '[1,2,3]'
- Variabili speciali:
Variabile
Descrizione
_NROW_
il numero di riga a base 0
_RECNUM_
il numero di riga a base 1
_NTOT_
il numero totale dei record
Le funzioni possono essere scritte indifferentemente in maiuscolo o minuscolo.
Esempi con sintassi alternative:
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | # valori validi
:x1
"x1"
"VALID(x1)"
# valori mancanti
:x1 => nil
"!x1" # solo quando l'espressione è composta solo da un nome di variabile
"BLANK(x1)"
"NOT(VALID(x1))"
"!x1 AND x2=1" # NON E' VALIDO! usare invece:
"BLANK(x1) AND x2=1)"
"NOT(VALID(x1)) AND x2=1)"
# uguale a un valore
{:sesso => 1}
"sesso=1"
# minore di un valore
"etanum<=25"
# due condizioni diverse in AND
"#sesso=1 AND etanum<25"
# più valori di una stessa variabile(in OR)
:region => [1,3,7]
"ANY(region,1,3,7)"
# range
:etanum => 18..24
# estrae il mese da una stringa e lo strasforma in intero
compute :mese => "INT(MID(giorno,6,2))"
# genera data da anno, mese, giorno
compute :date_ril => "YMD(anno_rilevaz, mese_rilevaz, 1)", :type => :date
# ricodifica i valori di v1
compute :v1r => "RECODE(v1, VALUES(1,2,6),1, VALUES(3,5),2, VALUES(4,7),3)"
# genera una numerazione progressiva dei record
compute :row_id => "RECNUM()"
|
Spesso si ha la necessità di scrivere in una espressione un elenco di variabili, è possibile utilizzare la funzione s() e il metodo .to_list degli Array. Oppure, più semplicemente, il metodo l() Funzioni di utilità.
1 2 3 4 5 6 7 | compute :n9d1 => "COUNT(9,#{s(:d7_,1..7).to_list})"
# o
compute :n9d1 => "COUNT(9,#{l(:d7_,1..7)})"
# o
compute :n9d1 => "COUNT(9," + l(:d7_,1..7) + ")"
# equivale a
compute :n9d1 => "COUNT(9,d7_1,d7_2,d7_3,d7_4,d7_5,d7_6,d7_7)"
|
MANY, MALL, MNONE e MCOUNT confrontano contemporaneamente più di un valore di un set di variabili:
1 2 3 4 5 6 7 8 9 10 11 12 13 | levels s(:v3_,1..10) => {1=>"Molto", 2=>"Abbastanza", 3=>"Poco", 4=>"Per Niente", 9=>"Non indica"}
# il numero di occorrenze dei codici 1 o 2 nella batteria v3
compute :x3count => "MCOUNT(VALUES(1,2),#{l(:v1_,1..10)})"
# almeno in una delle v3 è stato citato il codice 1 o il codice 2?
compute :x3any => "IF(MANY(VALUES(1,2),#{l(:v1_,1..10)}),1,0)"
# in tutte le v3 è stato citato o il codice 1 o il codice 2?
compute :x3all => "IF(MALL(VALUES(1,2),#{l(:v1_,1..10)}),1,0)"
# in nessuna delle v3 è stato citato o il codice 1 o il codice 2?
compute :x3none => "IF(MNONE(VALUES(1,2),#{l(:v1_,1..10)}),1,0)"
|
any¶
La funzione helper any genera l’espressione MANY o ANY:
1 2 3 | any(s(:d12_, 1..5), [1,2..4]) # => "MANY(VALUES(1,2,3,4), d12_1,d12_2,d12_3,d12_4,d12_5)"
any(s(:d12_, 1..5), 1) # => "ANY(1, d12_1,d12_2,d12_3,d12_4,d12_5)"
any([:d12_1, :d12_2], [2,3]) # => "MANY(VALUES(2,3), d12_1,d12_2)"
|
add_function¶
add_function permette di definire delle nuove funzioni all’interno dello script:
1 2 3 4 5 6 7 8 9 10 11 12 | add_function(name, type, body)
add_function(:myfunction, :string, ->(text) {
text.gsub(/(.+?) anni/, 'Age \1')
})
compute :x4 => "MYFUNCTION(level(eta))"
# se ci sono almeno 3 valori 5 nella batteria di items mette 1 altrimenti 0
add_function(:more3, :number, ->(*args) {
args.compact.select{|x| x == 5}.count >= 3 ? 1 : 0
})
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # Eesempi di implementazione di funzioni esistenti:
# COUNT
add_function(:count, :integer, ->(value, *args) {
args.compact.select{|x| x == value}.count
})
# TITLEIZE
add_function(:titleize, :string, ->(value) {
(value||'').to_s.split(' ').map{|x| x.capitalize}.join(' ')
})
# ROUND
add_function(:round, :numeric, ->(numeric, places=nil) {
numeric ? numeric.round(places||0) : nil
})
|