2
$\begingroup$

Is there an optimized way to perform this function "PolynomialFeatures" in R? I'm interested in creating a matrix of polynomial features i.e. interactions between two columns among all columns but I can't find a base function or a package that does this optimally in R and I don't want to import data from a Python script using sklearn's PolynomialFeatures function into R.

The idea is to transform this:

array([[0, 1],
       [2, 3],
       [4, 5]])

into this:

array([[ 1.,  0.,  1.,  0.,  0.,  1.],
       [ 1.,  2.,  3.,  4.,  6.,  9.],
       [ 1.,  4.,  5., 16., 20., 25.]])

Intercept and only-interaction options are well, optional. I could expand-omit those myself.

$\endgroup$

1 Answer 1

5
+50
$\begingroup$

You can use two methods: one that takes a formula argument or if you are not using formula you can use model.matrix.

You can do the following:

# Using the same data from the question:
data <- data.table(A = c(0, 2, 4), 
                   B = c(1, 3, 5))

> data

   A B
1: 0 1
2: 2 3
3: 4 5

If only the raw data and the interactions are required

formula = y ~ .^2 

model.matrix(formula, data=data)
  (Intercept) A B A:B
1           1 0 1   0
2           1 2 3   6
3           1 4 5  20

If raw data, squared columns, interactions and intercept are needed, just like the question

You can use the following formula for all variables:

formula = y ~ .^2 + poly(var, 2, raw=TRUE)[, 2] ... etc

In addition you can paste the variables names automatically. Formula based on this post

formula <- as.formula(paste(' ~ .^2 + ',paste('poly(',colnames(data),',2, raw=TRUE)[, 2]',collapse = ' + ')))

> formula 

~.^2 + poly(A, 2, raw = TRUE)[, 2] + poly(B, 2, raw = TRUE)[, 2]

> model.matrix(formula, data=data)

  (Intercept) A B poly(A, 2, raw = TRUE)[, 2] poly(B, 2, raw = TRUE)[, 2] A:B
1           1 0 1                           0                           1   0
2           1 2 3                           4                           9   6
3           1 4 5                          16                          25  20

The resulting dataframe is identical to the array in the question.

If squared columns, interactions and intercept are needed.

> formula <- as.formula(paste(' ~ A:B + ',paste('poly(',colnames(data),',2, raw=TRUE)[, 2]',collapse = ' + ')))

> formula
~A:B + poly(A, 2, raw = TRUE)[, 2] + poly(B, 2, raw = TRUE)[, 2]

>  model.matrix(formula, data=data)
  (Intercept) poly(A, 2, raw = TRUE)[, 2] poly(B, 2, raw = TRUE)[, 2] A:B
1           1                           0                           1   0
2           1                           4                           9   6
3           1                          16                          25  20
$\endgroup$
1
  • $\begingroup$ This was extremely useful because I need it both for formulas and other functions that don't have that option. $\endgroup$
    – wacax
    Commented Dec 19, 2018 at 20:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.