parsnip extract_fit_engine() in R: Get the Engine Model
The parsnip extract_fit_engine() function in R returns the raw, engine-specific model object stored inside a fitted model_fit or workflow, such as the underlying lm or ranger fit.
extract_fit_engine(fit) # raw engine model object extract_fit_engine(wf_fit) # works on a fitted workflow too summary(extract_fit_engine(fit)) # run engine-specific summary() extract_fit_engine(fit)$coefficients # reach into engine internals class(extract_fit_engine(fit)) # confirm the engine class plot(extract_fit_engine(lm_fit)) # engine diagnostic plots
Need explanation? Read on for examples and pitfalls.
What extract_fit_engine() does
extract_fit_engine() unwraps a parsnip fit and hands you the model object the engine actually built. When you call fit() on a parsnip specification, parsnip stores the native result inside a model_fit wrapper. A model fit with the lm engine holds a real lm object; one fit with ranger holds a ranger object. extract_fit_engine() reaches in and returns that object.
You need this whenever a function only understands the native object. parsnip gives you an engine-agnostic interface, but tools like summary(), confint(), anova(), car::vif(), or the plot() diagnostics for lm dispatch on the original class. They have no idea what a model_fit is.
The function is an S3 generic re-exported from the generics package. parsnip supplies the method for model_fit objects, workflows supplies one for fitted workflow objects, and tune adds one for last_fit() results. The same call therefore works at every layer of a tidymodels pipeline.
For a parsnip model_fit, the method is a thin accessor: it returns the element x$fit. Reaching for fit_object$fit by hand would do the same thing, but extract_fit_engine() is the supported API and stays correct if parsnip changes its internals.
extract_fit_engine() syntax and arguments
The signature is minimal because the function only locates an object, it does not compute anything. It is an S3 generic, so the method that runs depends on the class of x.
| Argument | Description |
|---|---|
x |
A fitted object: a parsnip model_fit, a fitted workflow, or a last_fit() result. |
... |
Currently unused for the parsnip and workflow methods. Reserved for future methods. |
The return value is whatever the engine produced. Its class is the engine's class, not a tidymodels class, so always confirm it with class() before you assume which functions apply.
Passing an unfitted specification raises an error. extract_fit_engine() needs a trained object, because there is no engine fit until fit() has run. Extract from the result of fit(), never from the linear_reg() spec itself.
Extract the engine fit: four examples
Each example uses a built-in dataset so you can run it as-is. Start by training a linear regression model through the parsnip interface.
Example 1 extracts an lm object. The returned object carries the lm class, so every base R tool for linear models works on it.
Example 2 runs lm-specific tools. Confidence intervals are not part of the parsnip interface, but confint() works once you have the raw lm.
Each predictor has an interval that excludes zero, so both wt and hp are significant at the 5% level. This is the kind of output you reach the engine object to obtain.
Example 3 extracts a ranger random forest. A different engine returns a different class, with its own fields.
The ranger object exposes internals such as num.trees and mtry that have no equivalent in the parsnip wrapper. Extracting the engine fit is the only way to inspect them.
Example 4 extracts from a workflow. extract_fit_engine() works directly on a fitted workflow, so you do not have to pull the parsnip fit first.
The workflow method digs through the workflow to the parsnip fit and then to the engine object in one step. The same call covers a bare model_fit and a full workflow.
summary(extract_fit_engine(lm_fit)) or plot(extract_fit_engine(lm_fit)) directly. There is no need to store the engine object in a variable unless you reuse it several times.extract_fit_engine() vs extract_fit_parsnip()
Pick extract_fit_engine() for the native object and extract_fit_parsnip() for the parsnip wrapper. Both pull something out of a fitted workflow, but they stop at different layers.
| Aspect | extract_fit_engine() |
extract_fit_parsnip() |
|---|---|---|
| Returns | The native engine object | The parsnip model_fit wrapper |
| Class | Engine class (lm, ranger) |
model_fit |
| Use for | summary(), confint(), engine internals |
tidy(), glance(), predict() |
| Layer | Deepest, engine level | One level up, parsnip level |
The decision rule is about which functions you plan to call next. If the next step is a base R or engine-specific function, extract the engine object. If the next step is a broom verb or a parsnip predict(), extract the parsnip fit, because those methods dispatch on model_fit.
workflow, extract_fit_engine() and extract_fit_parsnip() both reach the model. Use extract_recipe() or extract_spec_parsnip() when you need the workflow's preprocessing or the untrained specification instead.Common pitfalls
Two mistakes cause most extract_fit_engine() trouble. Each has a clear fix.
The first is predicting with the extracted object after a recipe was applied. If your workflow used a recipe, the engine fit was trained on preprocessed columns. Calling predict() on the raw engine object with the original data feeds it the wrong columns and returns wrong numbers. Always predict through the parsnip fit or the workflow, which replay the preprocessing for you.
The second is assuming every engine returns the same class. extract_fit_engine() on an lm engine gives an lm, but on a glmnet engine it gives an elnet or lognet, and on xgboost it gives an xgb.Booster. A script that hard-codes summary() will break when the engine changes. Confirm with class() first.
predict() on the model_fit or workflow and treat the engine object as inspect-only.Try it yourself
Try it: Fit a linear_reg() model of mpg on disp and drat with the lm engine, extract the engine object, and store its class in ex_class.
Click to reveal solution
Explanation: extract_fit_engine() returns the native object the engine built, so its class is lm, not model_fit. That lm object accepts every base R linear-model tool.
Related parsnip functions
extract_fit_engine() belongs to a family of tidymodels extractors. These functions cover the rest of what you might pull from a fit or a workflow.
extract_fit_parsnip()returns the parsnipmodel_fitwrapper instead of the engine object.extract_spec_parsnip()returns the untrained model specification from a workflow.extract_recipe()returns the prepped recipe used by a workflow.tidy()returns a tibble with one row per model coefficient.glance()returns a one-row tibble of whole-model statistics.
See the official parsnip reference for the full list of extractor methods.
FAQ
What does extract_fit_engine() return for a parsnip model?
extract_fit_engine() returns the native model object the engine produced, not a tidymodels wrapper. A model fit with the lm engine returns an lm object, a ranger engine returns a ranger object, and an xgboost engine returns an xgb.Booster. The class is whatever the engine package defines, so you can pass the result to any function that understands that class, such as summary(), confint(), or plot().
What is the difference between extract_fit_engine() and extract_fit_parsnip()?
extract_fit_engine() returns the deepest object, the raw engine fit with its native class. extract_fit_parsnip() stops one level higher and returns the parsnip model_fit wrapper. Use extract_fit_engine() when the next call is a base R or engine-specific function, and extract_fit_parsnip() when the next call is a broom verb like tidy() or glance(), since those dispatch on model_fit.
Can I call extract_fit_engine() on a workflow?
Yes. The workflows package supplies a method for fitted workflow objects, so extract_fit_engine(wf_fit) works directly. It digs through the workflow to the parsnip fit and then to the engine object in a single call. The workflow must be fitted first; calling it on an unfitted workflow raises an error because no engine fit exists yet.
Why should I avoid predicting with the extracted engine object?
The engine object was trained on the columns parsnip or a recipe produced, which may include dummy variables, normalized values, or transformed terms. Predicting on the raw engine object with your original data skips that preprocessing and returns incorrect results. Always call predict() on the model_fit or workflow, which replays the preprocessing, and treat the engine object as inspect-only.