FMM
FMM

Reputation: 2005

Map a function over a vector

I have the following x and y:

set.seed(1234)
x <- seq(1, 1000, 1)
y <- rnorm(1000)

And I need to model them using smooth.spline:

model <- smooth.spline(x, y, nknots = 10)

The problem is that I need to fit this model modifying nknots every time. The vector indicating the knots is the following:

myknots <- seq(5, 15, 1)

I thought creating my own function, like:

myfoo <- function(x, y, nknots){
  smooth.spline(x, y, nknots = nknots)
}

But I can't find a straight way of doing it. I rather use the purrr package. Any ideas?

Upvotes: 2

Views: 151

Answers (2)

Spacedman
Spacedman

Reputation: 94202

You can do this without needing the added burden of loading extra packages and relying on them to never change using base::Vectorize in a one-liner:

> alls = Vectorize(smooth.spline,"nknots",SIMPLIFY=FALSE)(x=x,y=y,nknots=myknots)

This returns a list where each element is a smooth.spline output for each value of myknots:

> alls[[1]]
Call:
(function (x, y = NULL, w = NULL, df, spar = NULL, lambda = NULL, 
    cv = FALSE, all.knots = FALSE, nknots = .nknots.smspl, keep.data = TRUE, 
  ...

Smoothing Parameter  spar= 0.1318881  lambda= 0.01540768 (14 iterations)
Equivalent Degrees of Freedom (Df): 5.244268
Penalized Criterion (RSS): 984.4824
GCV: 0.99489
> alls[[2]]
Call:
(function (x, y = NULL, w = NULL, df, spar = NULL, lambda = NULL, 
    cv = FALSE, all.knots = FALSE, nknots = .nknots.smspl, keep.data = TRUE, 
  ...

Smoothing Parameter  spar= 0.2285265  lambda= 0.03658625 (12 iterations)
Equivalent Degrees of Freedom (Df): 5.006371
Penalized Criterion (RSS): 984.8108
GCV: 0.994746

Keeping dependencies to a minimum is good practice.

Upvotes: 4

akrun
akrun

Reputation: 887148

With purrr, we use map

library(purrr)
map(myknots,  ~ myfoo(x, y, nknots = .x))

Upvotes: 3

Related Questions