Product: TIBCO Spotfire®

**Problem:**

Data function returns "Error in as.data.frame.default" "cannot coerce class '"summary.lm"' into a data.frame"

**Solution:**

A TERR data function that calls summary() for a linear regression model created using lm() will throw the following error and stack trace when the data function is set up to return the output from summary() to a Spotfire data table:

TIBCO Enterprise Runtime for R returned an error: 'Error in as.data.frame.default(passed.args[[i]], stringsAsFactors = s : cannot coerce class '"summary.lm"' into a data.frame'.

at Spotfire.Dxp.Data.DataFunctions.Executors.LocalFunctionClient.OnExecuting(FunctionClient funcClient)

at Spotfire.Dxp.Data.DataFunctions.Executors.AbstractFunctionClient.<RunFunction>d__0.MoveNext()

at Spotfire.Dxp.Data.DataFunctions.Executors.SPlusFunctionExecutor.<ExecuteFunction>d__0.MoveNext()

at Spotfire.Dxp.Data.DataFunctions.DataFunctionExecutorService.<ExecuteFunction>d__6.MoveNext()

This is as designed.

The output from a call to lm() or summary() is a TERR list object (object of storage mode "list") whose structure cannot be converted into a TERR data frame (object of class "data.frame"). This is also true for most of the statistical modeling functions in R and TERR (such as aov(), glm(), loess() and nls(), for example) and their summary() methods. Only a TERR data frame can be converted into a Spotfire data table when the result is returned to Spotfire from its TERR engine. The error message indicates that Spotfire's framework for its TERR data functions has failed to make this conversion of a non-rectangular (not table-shaped) list object into a data frame, as expected.
There is no way to return all of the regression summary result from TERR to Spotfire in a single step, because it is a composite result that cannot fit into any of the data function output handlers. Individual components can be extracted from this result and returned separately from TERR to Spotfire, however.

Details:

TERR's statistical modeling functions and their summary functions all produce several different results that do not fit into a table format. They are stored as components in a TERR list object (object of class "list") and then an additional class (such as "lm" or "summary.lm") is assigned to the list object. Each of these TERR classes has class-specific methods defined for unpacking its components from the list object and performing common tasks with them.

By design, the Spotfire architecture does not support a data structure analogous to a TERR list. So there is no handler for a TERR list in Spotfire's data function framework.

The display on the TERR Console screen when you type the name of the summary result at the command prompt is a conveniently formatted display provided by the 'print.summary.lm()' method of TERR's generic 'print()' function. But this printed display does not reflect the actual contents and structure of the summary result, which are stored in a TERR object structure that has no Spotfire equivalent.

Individual components of this composite list structure can be extracted from it in TERR (using the "$" operator, for example), then saved as independent TERR objects and returned individually to Spotfire, but they cannot all be returned together as a unit.

Passing the summary object directly to TERR's 'print.default()' method will show all of its structure and contents as a TERR list, including the names of all of the components.

Passing the summary object to TERR's 'names()' function will list the names of all of its components.

The TERR example shown below does the following:

- Loads TERR's optional "Sdatasets" package.

- Calls 'lm()' to build a linear regression model of columns from the "Sdatasets" package's 60-row 'fuel.frame' example data frame.

- Calls 'summary()' to build a TERR object of class "summary.lm" from that linear regression model.

- Examines the list structure of the "summary.lm" class.

- Examines the list object's components which can each be extracted from the list by name using the "$" operator.

- Extracts the "residuals" component as a one-column data frame that can be returned to Spotfire as an output Table.

- Extracts the "r.squared" component as a single value that can be returned to Spotfire as an output Value.

- Extracts the "coefficients" component, which is a 3x3 matrix, and converts it into a data frame, which can be returned to Spotfire as an output Table.

....................

Unpacking components from a TERR object that is stored as a list, for return to Spotfire via Spotfire data function Output handlers:

==============

TIBCO Software Inc. Confidential Information

Copyright (C) 2011-2017 TIBCO Software Inc. ALL RIGHTS RESERVED

TIBCO Enterprise Runtime for R version 4.3.0 for Microsoft Windows 64-bit

Type 'help()' for help.

Type 'q()' to quit.

>

>

>

>

> # This example uses the 'fuel.frame' example data frame

> # that is contained in TERR's optional built-in "Sdatasets"

> # package:

>

>

> library( "Sdatasets" )

>

>

>

> search()

[1] ".GlobalEnv" "package:Sdatasets" "package:stats"

[4] "package:graphics" "package:grDevices" "package:utils"

[7] "package:methods" "package:base"

>

>

>

> find( "fuel.frame" )

[1] "package:Sdatasets"

>

>

>

>

> # This call to the 'lm()' function builds a linear regression

> # model with the "Mileage" column as the the dependent variable

> # and the "Weight" and "Disp." columns as explanatory variables:

>

>

> ff.lm <- lm( Mileage ~ Weight + Disp., data = fuel.frame )

>

>

>

> # The result is a TERR object of class "lm" whose underlying

> # structure is a TERR object of class "list" with named components:

>

>

> class( ff.lm )

[1] "lm"

>

>

> storage.mode( ff.lm )

[1] "list"

>

>

>

> names( ff.lm )

[1] "coefficients" "residuals" "effects" "rank"

[5] "fitted.values" "assign" "qr" "df.residual"

[9] "xlevels" "call" "terms" "model"

>

>

>

>

> # This call to 'summary()' creates a TERR object of class "summary.lm"

> # whose underlying structure is also a TERR object of class "list"

> # with named components of various classes, sizes, and structures:

>

>

> ff.summary.lm <- summary( ff.lm )

>

>

>

> class( ff.summary.lm )

[1] "summary.lm"

>

>

>

> storage.mode( ff.summary.lm )

[1] "list"

>

>

>

> names( ff.summary.lm )

[1] "call" "terms" "residuals" "coefficients"

[5] "aliased" "sigma" "df" "r.squared"

[9] "adj.r.squared" "fstatistic" "cov.unscaled"

>

>

>

>

>

> sapply( ff.summary.lm, class )

$call

[1] "call"

$terms

[1] "terms" "formula"

$residuals

[1] "numeric"

$coefficients

[1] "matrix"

$aliased

[1] "logical"

$sigma

[1] "numeric"

$df

[1] "integer"

$r.squared

[1] "numeric"

$adj.r.squared

[1] "numeric"

$fstatistic

[1] "numeric"

$cov.unscaled

[1] "matrix"

>

>

>

>

>

> sapply( ff.summary.lm, length )

call terms residuals coefficients aliased

3 3 60 12 3

sigma df r.squared adj.r.squared fstatistic

1 3 1 1 3

cov.unscaled

9

>

>

>

>

> # The "residuals" component of the list is a named vector with many values,

> # so it needs to be converted into a one-column data frame,

> # then returned to Spotfire as a one-column output Table:

>

>

> ff.summary.lm.residuals.df <- data.frame( Residuals = ff.summary.lm$residuals )

>

>

> ff.summary.lm.residuals.df[ 1:5, , drop = FALSE ]

Residuals

Eagle Summit 4 5.548222

Ford Escort 4 3.895240

Ford Festiva 4 3.831704

Honda Civic 4 2.151840

Mazda Protege 4 3.645323

>

>

>

> # The "r.squared" component of the list has only one value,

> # so it can be extracted from the list and sent to Spotfire

> # as an output Value:

>

>

> ff.summary.lm.r.squared <- ff.summary.lm$r.squared

>

>

>

> ff.summary.lm.r.squared

[1] 0.7192712

>

>

>

>

> # The "coefficients" component of the list is a 3-by-3 matrix,

> # so it can be extracted from the list, then converted directly

> # into a data frame, then returned to Spotfire as an output Table:

>

>

>

> ff.summary.lm.coefficients <- as.data.frame( ff.summary.lm$coefficients )

>

>

>

> ff.summary.lm.coefficients

Estimate Std. Error t value Pr(>|t|)

(Intercept) 48.039427901 2.263134178 21.2269464 9.605354e-029

Weight -0.007927444 0.001138579 -6.9625797 3.672905e-009

Disp. -0.003024662 0.010424170 -0.2901586 7.727479e-001

>

>

>

> class( ff.summary.lm.coefficients )

[1] "data.frame"

>

>

==============

## Comments

0 comments

Article is closed for comments.