The t-test as a COM service
Here we define a simple COM server that has just two methods.
The first is a wrapper around the
t.test function.
The second allows clients to generate a sample from Normal
distribution.
As usual, we combine the two methods into a list of functions
and create a COM class definition using the
the function
SCOMFunctionClass.
def = SCOMFunctionClass(list(ttest = function(x, ...) t.test(as.numeric(x),...), rnorm = rnorm), name = "R.TTest")
def@classId = getuuid("11D2A4BC-7EBC-4236-80FF-2588EFCD8821")
|
---|
And next, we register the definition with R and the Windows registry
so that it is now available to clients.
registerCOMClass(def, registry = TRUE)
|
---|
Note that in this case, we are providing a list of functions directly.
This differs from the Normal distribution server in
Sobject. In that case, the list of
functions used in a COM instance needed to share an environment, and a
separate one for each COM instance. As a result, there we used the
SCOMIDispatch to define the COM class. Here we use
SCOMFunctionClass which takes the list of functions
directly.
Now we are ready to use this from a client. Our example will use
Perl. We start by creating an instance of the COM class.
# Call with ActiveState Perl
use Win32::OLE;
$t = Win32::OLE->new("R.TTest") || die "Can't create R.TTest COM object";
|
---|
Next, we call the
ttest with
data stored in Perl.
# Following currently is transferred as a list in S, not a numeric.
@x = (0.2795290, 1.2010954, -0.1396027, 0.1742421, -2.1921724 , 0.4139593, -0.3025258, -0.1818093, 0.6793734, 0.7978106);
$val = $t->ttest(\@x);
|
---|
The result is an S object of class
htest.
The converter mechanism in the
RDCOMServer
uses the default mechanism for exporting these non-primitive
objects and returns another COM object which provides access
to all of the fields and attributes of this object and
also allows one to call top-level S functions with
this object as the first argument.
Note how we get the
statistic,
parameter and
estimate values as
if they were regular properties of the COM or Perl object.
print "Result: $val\n";
$x = $val->statistic;
$d = $val->parameter;
$mean = $val->estimate;
print "Statistic: $x ($d) $mean\n";
|
---|
Now, let's use the
rnorm
to generate data in the server, transfer it back
to the client and then pass that back to the server
in the call to
ttest.
(The round trips of the data can be avoided if we
designed the COM object to have state and store the data
locally. This is a very different idea, sometimes useful
and sometimes not.)
print "Next stage\n";
# Now we create a second COM object within S and
# use it to generate
$normal = Win32::OLE->new("SNormal");
@data = @{$normal->sample(100)};
$val = $t->ttest(\@data);
$x = $val->statistic;
$d = $val->parameter;
$mean = $val->estimate;
print "Statistic: $x ($d) $mean\n";
|
---|