Consultar l'R per a obtenir informació

En alguns casos, és possible que vulgueu obtenir més informació de l'R, que es presentarà a la interfície d'usuari del vostre connector. Per exemple, podeu oferir una selecció dels nivells d'un factor que l'usuari ha seleccionat per a l'anàlisi. Des de la versió 0.6.2 del RKWard és possible fer-ho. Abans de començar, és important que tingueu present algunes advertències:

El codi R que s'executa des de dins de la lògica de la interfície d'usuari del connector s'avalua en el bucle d'esdeveniments de l'R, el que significa que es poden executar mentre s'estan executant altres càlculs. Això és per a assegurar-vos que la interfície d'usuari del vostre connector es pugui utilitzar, fins i tot mentre l'R estigui ocupat fent altres coses. Tanmateix, això fa que sigui molt important que el seu codi no tingui efectes secundaris. En particular:

  • No fa cap assignació a «.GlobalEnv» o qualsevol altre entorn no local.

  • No imprimeix res al fitxer de sortida.

  • No traça res en la pantalla.

  • En general, no faci res que tingui efectes secundaris. El vostre codi pot llegir informació, no «fer» altres coses.

Amb això en ment, aquí està el patró general. Ho utilitzareu dins d'una secció lògica IU amb scripts:

<script><![CDATA[
                                last_command_id = -1;
                                gui.addChangeCommand ("variable", "update ()");
                                update = function () {
                                        gui.setValue ("selector.enabled", 0);
                                        variable = gui.getValue ("variable");
                                        if (variable == "") return;

                                        last_command_id = doRCommand ('levels (' + variable + ')', "commandFinished");
                                }

                                commandFinished = function (result, id) {
                                        if (id != last_command_id) return;  // another result is about to arrive
                                        if (typeof (result) == "undefined") {
                                                gui.setListValue ("selector.available", Array ("ERROR"));
                                                return;
                                        }
                                        gui.setValue ("selector.enabled", 1);
                                        gui.setListValue ("selector.available", result);
                                }
                ]]></script>
        

Aquí, variable és una propietat que conté un nom d'objecte (p. ex., dins d'un <varslot>). Sempre que això canviï, voldreu actualitzar la visualització dels nivells dins del <valueselector>, anomenat selector. La funció clau aquí és doRCommand(), que pren com a primer paràmetre la cadena d'ordre a executar, i com a segon paràmetre el nom d'una funció a cridar, quan l'ordre hagi finalitzat. Tingueu en compte que l'ordre s'està executant asíncronament, i això fa les coses una mica més complexes. Per a una cosa que voleu estar segur, el <valueselector> roman desactivat, mentre que no contingui informació actualitzada. Una altra cosa és que podríeu haver posat a la cua més d'una ordre, abans d'obtenir els primers resultats. Aquesta és la raó per la qual cada ordre té una "id", i la guardem en last_command_id per a una referència posterior.

Quan es fa l'ordre, es crida la crida de retorn especificada (commandFinished, en aquest cas) amb dos paràmetres: el resultat en si, i l'identificador de l'ordre corresponent. El resultat serà d'un tipus similar a la representació en R, és a dir, una matriu numèrica, si el resultat és numèric, etc. Fins i tot pot ser una list() de l'R, però en aquest cas es representarà com un Array() JS sense noms.

Cal tenir en compte que fins i tot aquest exemple és una mica simplificat. En realitat, haureu de prendre precaucions addicionals, p. ex., per a evitar posar una quantitat extrema de nivells al selector. La bona notícia és que probablement no cal fer tot això vós mateix. L'exemple anterior es pren del connector rkward::level_select, per exemple, que simplement podeu incrustar en el vostre propi connector. Fins i tot us permet especificar una expressió diferent per a executar en lloc de levels().