Da boste dobili idejo, kako izgleda “skriptiranje vtičnika”,v primerjavi z neposrednim pristopom, ki ste ga videli v prejšnjih poglavjih, bomo ponovno ustvarili celoten vtičnik t-test -- tokrat samo z R funkcijami paketa rkwarddev.
Namig
Paket bo dodal novo GUI pogovorno okno za RKWard pod → → . Kot že ime pove, lahko ustvarite okostja vtičnikov za nadaljnje urejanje z njim. To pogovorno okno je nato ustvaril rkwarddev skript, ki ga najdete v “demo” imeniku nameščenega paketa in izvornih paketov,kot dodaten primer. Zaženete ga lahko tudi tako, da pokličete demo("skeleton_dialog")
Takoj boste opazili, da je potek dela precej drugačen: v nasprotju z neposrednim pisanjem kode XML ne začnete z definicijo <document>, temveč neposredno z elementi vtičnika, ki jih želite imeti v dialogu. Vsak element vmesnika - naj bodo to potrditvena polja, spustni meniji, spremenljive reže ali karkoli drugega - lahko dodelite posameznim R objektom in nato združite te objekte v dejanski GUI. Paket ima funkcije za vsako oznako XML, ki jo je mogoče uporabiti za definiranje vtičnika GUI, in večina jih ima celo isto ime, le s predpono rk. XML.*. Na primer definiranje <varselector> in dveh elementov <varslot> za "x" in "y" primera t-testa lahko izvedete tako:
variables <- rk.XML.varselector(id.name="vars")
var.x <- rk.XML.varslot("compare", source=variables, types="number", required=TRUE, id.name="x")
var.y <- rk.XML.varslot("against", source=variables, types="number", required=TRUE, id.name="y")
Najbolj zanimiva podrobnost je verjetno source=spremenljivke: Pomembna značilnost paketa je, da lahko vse funkcije ustvarijo samodejne ID-je, tako da vam ni treba razmišljati o nobeni njihovi vrednosti id ali si jih zapomniti, da se nanašajo na določeni element vtičnika. Lahko preprosto podate R predmete kot referenca, kot vse funkcije, ki potrebujejo ID nekega drugega elementa, ga lahko tudi preberejo iz teh predmetov. rk.XML.varselector() je malo poseben, saj običajno nima posebne vsebine, iz katere bi lahko naredil ID (lahko, vendar le, če določite oznako), zato moramo nastaviti ime ID-ja. Toda rk.XML.varslot() ne potrebuje id.nameargumentov tukaj, tako da bi to zadostovalo:
variables <- rk.XML.varselector(id.name="vars")
var.x <- rk.XML.varslot("compare", source=variables, types="number", required=TRUE)
var.y <- rk.XML.varslot("against", source=variables, types="number", required=TRUE)
Če želite ponovno ustvariti primer kode do točke, bi morali nastavitivse ID vrednosti ročno. Ker pa nam bo paket olajšal življenje,od zdaj naprej nam to ne bo več mar.
Namig
rkwarddev je zmožen veliko avtomatizacije, da vam pomaga zgraditi vaše vtičnike. Vendar je morda bolje, da ga ne uporabite v polni meri. Če je vaš cilj ustvariti kodo, ki ne deluje lelahko pa ga tudi človek zlahka prebere in primerja z vašim generatorskim skriptom bi morali razmisliti o tem, da vedno nastavite uporabne ID-je s id.name. Poimenovanje vašega R predmeti, ki so enaki tem ID-jem, bodo prav tako pomagali k pridobivanju skriptne kode, ki je lahko razumljiva.
Če želite videti, kako je videti koda XML definiranega elementa, če želite jo izvozite v datoteko, lahko predmet preprosto pokličete po njegovem imenu. Torej, če ste klicali “var.x” v vaši R seji, bi morali videti nekaj podobnega:
<varslot id="vrsl_compare" label="primerjaj" source="vars" types="number" required="true" />
Nekatere oznake so uporabne le v kontekstu drugih. Zato je npr.ne boste našli funkcije za oznako <option>.Namesto tega so opredeljeni izbirni gumbi in spustni seznami, vključno z njihovimi možnostmi kot poimenovan seznam, kjer imena predstavljajo oznake, ki bodo prikazane vpogovornem oknu, njihova vrednost pa je imenovan vektor, ki ima lahko dva vnosa,val za vrednost možnosti in logično vrednostchk, da določite, ali je ta možnost privzeto označena.
test.hypothesis <- rk.XML.radio("using test hypothesis",
options=list(
"Two-sided"=c(val="two.sided"),
"First is greater"=c(val="greater"),
"Second is greater"=c(val="less")
)
)
Rezultat je videti takole:
<radio id="rad_usngtsth" label="using test hypothesis">
<option label="Two-sided" value="two.sided" />
<option label="First is greater" value="greater" />
<option label="Second is greater" value="less" />
</radio>
Vse, kar manjka elementom zavihka “Osnovne nastavitve”, je potrditveno polje za seznanjene vzorce in strukturiranje vseh teh elementov v vrsticah in stolpcih:
check.paired <- rk.XML.cbox("Paired sample", value="1", un.value="0")
basic.settings <- rk.XML.row(variables, rk.XML.col(var.x, var.y, test.hypothesis, check.paired))
rk.XML.cbox() je redka izjema, kjer ime funkcije ne vsebuje celotnega imena oznake, da prihranite nekaj tipkanja za ta pogosto uporabljen element. To zdaj vsebuje basic.settings:
<row id="row_vTFSPP10TF">
<varselector id="vars" />
<column id="clm_vrsTFSPP10">
<varslot id="vrsl_compare" label="compare" source="vars" types="number" required="true" />
<varslot id="vrsl_against" label="against" i18n_context="compare against" source="vars" types="number" required="true" />
<radio id="rad_usngtsth" label="using test hypothesis">
<option label="Two-sided" value="two.sided" />
<option label="First is greater" value="greater" />
<option label="Second is greater" value="less" />
</radio>
<checkbox id="chc_Pardsmpl" label="Paired sample" value="1" value_unchecked="0" />
</column>
</row>
Na podoben način bodo naslednje vrstice ustvarile R objekti za elemente zavihka “Možnosti”, ki predstavljajo funkcije za spinboxe, okvirje in raztezanje:
check.eqvar <- rk.XML.cbox("assume equal variances", value="1", un.value="0")
conf.level <- rk.XML.spinbox("confidence level", min=0, max=1, initial=0.95)
check.conf <- rk.XML.cbox("print confidence interval", val="1", chk=TRUE)
conf.frame <- rk.XML.frame(conf.level, check.conf, rk.XML.stretch(), label="Confidence Interval")
Vse, kar moramo storiti, je, da objekte združimo v zavihek in ga postavimo v pogovorno okno:
full.dialog <- rk.XML.dialog(
label="Two Variable t-Test",
rk.XML.tabbook(tabs=list("Basic settings"=basic.settings, "Options"=list(check.eqvar, conf.frame)))
)
Ustvarimo lahko tudi razdelek čarovnika z dvema stranema z uporabo istih predmetov, tako da bodo njuni ID-ji ekstrahirani za oznake <copy>:
full.wizard <- rk.XML.wizard(
label="Two Variable t-Test",
rk.XML.page(
rk.XML.text("As a first step, select the two variables you want to compare against
each other. And specify, which one you theorize to be greater. Select two-sided,
if your theory does not tell you, which variable is greater."),
rk.XML.copy(basic.settings)),
rk.XML.page(
rk.XML.text("Below are some advanced options. It is generally safe not to assume the
variables have equal variances. An appropriate correction will be applied then.
Choosing \"assume equal variances\" may increase test-strength, however."),
rk.XML.copy(check.eqvar),
rk.XML.text("Sometimes it is helpful to get an estimate of the confidence interval of
the difference in means. Below you can specify whether one should be shown, and
which confidence-level should be applied (95% corresponds to a 5% level of
significance)."),
rk.XML.copy(conf.frame)))
To je to za GUI. Globalni dokument bo na koncu združil rk.plugin.skeleton().
Do zdaj se je morda zdelo, da uporaba paketa rkwarddev ni veliko pomagala. To se bo prav zdaj spremenilo.
Prvič, tako kot nam ni bilo treba skrbeti za ID-je elementov pri definiranju GUI postavitve, nam ni treba skrbeti za JavaScript imena spremenljivk v naslednjem koraku. Če želite več nadzora, lahko napišete navadno kodo JavaScriptin jo prilepite v ustvarjeno datoteko. Verjetno pa je veliko učinkoviteje to narediti na način rkwarddev.
Predvsem vam ni treba sami definirati nobene spremenljivke, saj lahko rk.plugin.skeleton() skenira vaš XML kodo in samodejno definira vse spremenljivke, ki jih boste verjetno potrebovali -- na primer, ne da bi se trudili vključiti potrditvenega polja, če pozneje ne uporabite njegove vrednosti ali stanja. Tako lahko začnemo pisati dejansko R kodo, ki takoj ustvari JS.
Namig
Funkcija rk.JS.scan() lahko skenira tudi obstoječe XML datoteke za spremenljivke.
Paket ima nekaj funkcij za konstrukte kode JS, ki se pogosto uporabljajo v RKWard vtičniki, kot je funkcija echo() ali pogoji if() {...} else {...}. Med JS in R je nekaj razlik, npr. za paste() v R vejico uporabljate za združevanje znakovnih nizov, medtem ko za echo() v JS uporabljate “+”, vrstice pa se morajo končati s podpičjem. Z uporabo R funkcije, lahko skoraj pozabite na te razlike in še naprej pišete R kodo.
Te funkcije lahko sprejmejo različne razrede vhodnih objektov: bodisi golo besedilo, R predmeti z XML kodo, kot je zgoraj, ali pa rezultate nekaterih drugih funkcij JS paketa. Na koncu boste vedno poklicali rk.paste.JS(), ki se obnaša podobno kot paste(), vendar jih bo glede na vhodne objekte nadomestil z njihovimi XML ID, JavaScript ime spremenljivke ali celo celoten JavaScript kodni bloki.
Za primer t-testa potrebujemo dva predmeta JS: enega za izračun rezultatov in enega za njihovo tiskanje v funkciji printout():
JS.calc <- rk.paste.JS(
echo("res <- t.test (x=", var.x, ", y=", var.y, ", hypothesis=\"", test.hypothesis, "\""),
js(
if(check.paired){
echo(", paired=TRUE")
},
if(!check.paired && check.eqvar){
echo(", var.equal=TRUE")
},
if(conf.level != "0.95"){
echo(", conf.level=", conf.level)
},
linebreaks=TRUE
),
echo(")\n"),
level=2
)
JS.print <- rk.paste.JS(echo("rk.print (res)\n"), level=2)
Kot lahko vidite, rkwarddev nudi tudi R implementacija funkcije echo(). Vrne natanko en niz znakov s svojo veljavno različico JS. Morda boste tudi opazili, da so vsi R predmeti tukaj tisti, ki smo jih ustvarili že prej. Samodejno bodo nadomeščeni s svojimi imeni spremenljivk, zato bi moralo biti to precej intuitivno. Kadarkoli potrebujete samo to zamenjavo, lahko uporabite funkcijo id(), ki prav tako vrne natanko en niz znakov iz vseh objektov, ki jih je prejel (lahko bi rekli, da se obnaša kot paste( ) z zelo specifično zamenjavo predmeta).
Funkcija js() je ovoj, ki vam omogoča uporabo if(){...} else {...} pogojev R, kot ste jih že uporabljali. Prevedeni bodo neposredno v kodo JS. Ohranja tudi nekatere operatorje, kot so <, >= ali ||, tako da lahko logično primerjate svoje R predmetov, ne da bi večino časa morali navajati. Oglejmo si nastali objekt “JS.calc”, ki zdaj vsebuje niz znakov s to vsebino:
echo("res <- t.test (x=" + vrslCompare + ", y=" + vrslAgainst + ", hypothesis=\"" + radUsngtsth + "\"");
if(chcPardsmpl) {
echo(", paired=TRUE");
} else {}
if(!chcPardsmpl && chcAssmqlvr) {
echo(", var.equal=TRUE");
} else {}
if(spnCnfdnclv != "0.95") {
echo(", conf.level=" + spnCnfdnclv);
} else {}
echo(")\n");
Opomba
Druga možnost je za ugnezdene pogoje if() vjs(), lahko uporabite ite()funkcijo, ki se obnaša podobno kot R-jeva ifelse().Vendar so pogojni stavki, izdelani z uporabo ite()običajno težje berljivi in jih je treba zamenjati s js() kadar koli je to mogoče.
Ta razdelek je zelo kratek: ni nam treba napisati .pluginmap sploh, ker ga samodejno lahko ustvari rk.plugin.skeleton(). Hierarhijo menija je mogoče določiti prek pluginmap možnosti:
[...]
pluginmap=list(
name="Two Variable t-Test",
hierarchy=list("analysis", "means", "t-Test"))
[...]
Tudi ta razdelek je zelo kratek: rk.plugin.skeleton() ne more napisati celotne strani pomoči iz informacij, ki jih ima. Lahko pa skenira XML dokument tudi za elemente, ki si verjetno zaslužijo vnos strani s pomočjo, in samodejno ustvari predlogo strani s pomočjo za naš vtičnik. Vse, kar moramo storiti kasneje, je, da napišemo nekaj vrstic za vsak naveden razdelek.
Namig
Funkcija rk.rkh.scan() lahko skenira tudi obstoječe XML datotek za ustvarjanje okostja datoteke pomoči.
Zdaj prihaja zadnji korak, v katerem bomo vse ustvarjene objekte predali rk.plugin.skeleton():
plugin.dir <- rk.plugin.skeleton("t-Test",
xml=list(
dialog=full.dialog,
wizard=full.wizard),
js=list(
results.header="Two Variable t-Test",
calculate=JS.calc,
printout=JS.print),
pluginmap=list(
name="Two Variable t-Test",
hierarchy=list("analysis", "means", "t-Test")),
load=TRUE,
edit=TRUE,
show=TRUE)
Datoteke bodo privzeto ustvarjene v časovnem imeniku. Zadnje tri možnosti niso potrebne, vendar so zelo priročne: load=TRUE samodejno doda nov vtičnik RKWard konfiguraciji (ker je v začasnem imeniku in zato bo prenehal obstajati, ko je RKWard zaprt, ga bo RKWard ob naslednjem zagonu znova samodejno odstranil), edit=TRUE bo odprl vse ustvarjene datoteke za urejanje v RKWard zavihki urejevalnika in show=TRUE bo poskušal neposredno zagnati vtičnik, tako da lahko brez klika preverite, kako je videti. Razmislite o dodajanju overwrite=TRUE, če boste svoj skript večkrat zagnali (npr. po spremembah kode), saj privzeto nobena datoteka ne bo prepisana.
Objekt rezultata “plugin.dir” vsebuje pot do imenika, v katerem je bil ustvarjen vtičnik. To je lahko uporabno v kombinaciji s funkcijo rk.build.package() za izdelavo dejanskega R paket za skupno rabo vtičnika z drugimi -- npr. tako, da ga pošljete na RKWard razvojno ekipo, ki bo dodana v naše skladišče vtičnikov.
Če povzamemo vse zgoraj navedeno, je tukaj celoten skript za ustvarjanje delujočega primera t-testa. Poleg že razložene kode tudi naloži paket, če je potrebno, in uporablja okolje local(), tako da vsi ustvarjeni objekti ne bodo končali v vašem trenutnem delovnem prostoru (razen “ plugin.dir”):
require(rkwarddev)
local({
variables <- rk.XML.varselector(id.name="vars")
var.x <- rk.XML.varslot("compare", source=variables, types="number", required=TRUE)
var.y <- rk.XML.varslot("against", source=variables, types="number", required=TRUE)
test.hypothesis <- rk.XML.radio("using test hypothesis",
options=list(
"Two-sided"=c(val="two.sided"),
"First is greater"=c(val="greater"),
"Second is greater"=c(val="less")
)
)
check.paired <- rk.XML.cbox("Paired sample", value="1", un.value="0")
basic.settings <- rk.XML.row(variables, rk.XML.col(var.x, var.y, test.hypothesis, check.paired))
check.eqvar <- rk.XML.cbox("assume equal variances", value="1", un.value="0")
conf.level <- rk.XML.spinbox("confidence level", min=0, max=1, initial=0.95)
check.conf <- rk.XML.cbox("print confidence interval", val="1", chk=TRUE)
conf.frame <- rk.XML.frame(conf.level, check.conf, rk.XML.stretch(), label="Confidence Interval")
full.dialog <- rk.XML.dialog(
label="Two Variable t-Test",
rk.XML.tabbook(tabs=list("Basic settings"=basic.settings, "Options"=list(check.eqvar, conf.frame)))
)
full.wizard <- rk.XML.wizard(
label="Two Variable t-Test",
rk.XML.page(
rk.XML.text("As a first step, select the two variables you want to compare against
each other. And specify, which one you theorize to be greater. Select two-sided,
if your theory does not tell you, which variable is greater."),
rk.XML.copy(basic.settings)),
rk.XML.page(
rk.XML.text("Below are some advanced options. It is generally safe not to assume the
variables have equal variances. An appropriate correction will be applied then.
Choosing \"assume equal variances\" may increase test-strength, however."),
rk.XML.copy(check.eqvar),
rk.XML.text("Sometimes it is helpful to get an estimate of the confidence interval of
the difference in means. Below you can specify whether one should be shown, and
which confidence-level should be applied (95% corresponds to a 5% level of
significance)."),
rk.XML.copy(conf.frame)))
JS.calc <- rk.paste.JS(
echo("res <- t.test (x=", var.x, ", y=", var.y, ", hypothesis=\"", test.hypothesis, "\""),
js(
if(check.paired){
echo(", paired=TRUE")
},
if(!check.paired && check.eqvar){
echo(", var.equal=TRUE")
},
if(conf.level != "0.95"){
echo(", conf.level=", conf.level)
},
linebreaks=TRUE
),
echo(")\n"), level=2)
JS.print <- rk.paste.JS(echo("rk.print (res)\n"), level=2)
plugin.dir <<- rk.plugin.skeleton("t-Test",
xml=list(
dialog=full.dialog,
wizard=full.wizard),
js=list(
results.header="Two Variable t-Test",
calculate=JS.calc,
printout=JS.print),
pluginmap=list(
name="Two Variable t-Test",
hierarchy=list("analysis", "means", "t-Test")),
load=TRUE,
edit=TRUE,
show=TRUE,
overwrite=TRUE)
})