Capitolo 5. Generare il codice di R dalle impostazioni della GUI

Utilizzare JavaScript nelle estensioni di RKWard

Ora abbiamo una GUI definita, ma dobbiamo ancora generare del codice R da quello. Per questo, abbiamo bisogno di un altro file di testo, code.js, situato nella stessa cartella di description.xml. Potreste avere familiarità o meno con JavaScript (o, per essere tecnicamente precisi: script ECMA). La documentazione su JS può essere trovata in abbondanza, sia in forma stampata che su Internet (ad es.: https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide). Ma per la maggior parte degli scopi non avrete bisogno di sapere molto di JS, poiché utilizzeremo solo alcune funzionalità di base.

Suggerimento

Dopo aver letto questo capitolo, date un'occhiata anche al pacchetto rkwarddev. Fornisce alcune funzioni R per creare codice JavaScript comunemente utilizzato in RKWard. Può anche rilevare automaticamente le variabili utilizzate in un file XML di un'estensione e creare codice JavaScript di base da cui partire.

Nota

Si presume che i file .js dell'estensione siano codificati in UTF-8. Assicurarsi di controllare la codifica dell'editor, se si utilizzano caratteri non ascii.

Per il test t a due variabili, il file code.js ha il seguente aspetto (con commenti nel mezzo):

preprocess()

function preprocess () {
}
                

Il file JS è organizzato in tre funzioni separate: preprocess(), calculate() e printout(). Questo perché non tutto il codice è necessario in tutte le fasi. Attualmente la funzione di pre-elaborazione non è realmente utilizzata in molti punti (in genere sarà omessa del tutto).

calculate()

function calculate () {
        echo ('res <- t.test (x=' + getString ("x") + ', y=' + getString ("y") + ', hypothesis="' + getString ("ipotesi") + '"' + getString ("varequal"));
        var conflevel = getString ("conflevel");
        if (conflevel != "0.95") echo (', conf.level=' + conflevel);
        echo (')\n');
}
                

Questa funzione genera l'attuale sintassi di R da eseguire dalle impostazioni della GUI. Vediamo questo in dettaglio: il codice da utilizzare è generato utilizzando l'istruzione echo(). Osservando l'istruzione echo() passo dopo passo, la prima parte è

res <- t.test (
                

come testo semplice. Successivamente dobbiamo inserire il valore selezionato dall'utente come prima variabile. Lo recuperiamo utilizzando getString ("x") e lo aggiungiamo alla stringa da «echo». Questo stampa il valore dell'elemento della GUI con id=""x": il nostro primo <checkbox>. Successivamente, aggiungiamo un ', ' e facciamo lo stesso per recuperare il valore dell'elemento "y" - il secondo <checkbox>. Per l'ipotesi (il gruppo <radio>) e le varianze uguali <checkbox>, la procedura è molto simile.

Nota

Invece di concatenare le stringhe utilizzando l'operatore +, puoi anche usare un «template literal», come questo (nota che la stringa è racchiusa tra apici inversi (`)):

echo(`res <- t.test (x=${ getString("x") }, y=${ getString("y") }, hypothesis="${ getString("hypothesis") }"`); // ecc.
                        

Tenere presente che invece di concatenare gli snippet di uscita con «+», è possibile anche utilizzare diverse istruzioni echo(). Tutto è stampato su una sola riga. Per produrre un'interruzione di riga nel codice generato, inserire un "\n" nella stringa stampata. In teoria, è possibile persino produrre molte righe con una singola istruzione echo, ma consigliamo limitarsi a una riga (o meno) di codice generato per echo().

Nota

Oltre a getString(), ci sono anche funzioni getBoolean(), che proveranno a restituire il valore come logico (adatto per l'uso in un'istruzione if() e getList(), che proveranno a restituire dati simili a quelli di una lista in un Array() JS. Ne mostreremo esempi in seguito.

Quando si cercano le estensioni esistenti, si troveranno molte estensioni utilizzando getValue(), invece di getString(), e in effetti le due sono quasi identiche. Tuttavia, l'utilizzo di getString(), getBoolean() e getList() è la pratica consigliata dalla versione 0.6.1.

Diventa un po 'più complicato per il livello di confidenza. Per ragioni estetiche, non vogliamo specificare esplicitamente il livello di confidenza da utilizzare, se corrisponde al valore predefinito. Quindi, invece di stampare il valore incondizionatamente, recuperiamo prima una variabile. Quindi controlliamo se quella variabile differisce da "0.95" e in tal caso stampiamo un argomento aggiuntivo. Infine, aggiungiamo una parentesi di chiusura e un'interruzione di riga: ")\n". Questo è tutto per la funzione di calcolo.

printout()

function printout () {
        echo ('rk.header (' + i18n ("Test t a due variabili") + ')\n');
        echo ('rk.print (res)\n');
}
                

E questo era tutto ciò che c'era nella funzione di stampa nella maggior parte dei casi. rk.header() stampa un'intestazione standard per i risultati. Tenere presente che nei file .js bisogna contrassegnare tutte le stringhe traducibili, usando i18n(), o alcuni comandi alternativi. Maggiori informazioni a riguardo sono disponibili nel capitolo sull'internazionalizzazione. È possibile anche aggiungere altre informazioni a questo, se lo si desidera, ad es.:

function printout () {
        new Header (i18n ("Test t a due variabili"))
                  .addFromUI ("varequal")
                  .add (i18n ("Livello di confidenza"), getString ("conflevel"))  // Nota: scritto in questo modo a scopo illustrativo. Più automatico:
        //        .addFromUI ("conflevel")
                  .print ();
echo ('rk.print (res)\n');
}
                

rk.print() utilizza il pacchetto R2HTML per fornire output HTML formattato. Un'altra funzione utile è rk.results(), che può anche generare diversi tipi di tabelle dei risultati. In caso di dubbio, tuttavia, usare semplicemente rk.print() e il gioco è fatto. La classe JS Header è un helper di livello JS per generare una chiamata a rk.header() (basta dare un'occhiata al codice R generato). In alcuni casi potreste voler chiamare echo ('rk.header (...)') direttamente per stampare un'intestazione per il vostro output.

Nota che internamente, l'output è un semplice documento HTML in questo momento. Pertanto potreste essere tentati di aggiungere HTML personalizzato. utilizzando rk.cat.output(). Anche se funzionerà, non fatelo. Il formato di output potrebbe cambiare (ad es. in ODF) in futuro, quindi è meglio non introdurre HTML codice specifico. Piuttosto mantenete le cose semplici con rk.header(), rk.print(), rk.results() e, se necessario, rk.print.literal(). Se questi non sembrano soddisfare le vostre esigenze di formattazione, contattateci sulla mailing list per ricevere assistenza.

Congratulazioni! Avete creato la vostra prima estensione. Continuare a leggere nei prossimi capitoli per concetti più avanzati.