0
votes

I have a data.frame with x,y coordinates and a grouping variable :

df<-data.frame(group=c(rep(1,3),rep(2,3),rep(3,3)),
               x=c(rep(c(1,2,3),3)),
               y=c(1,2,3,1,4,9,1,8,27))

I would like to have a splinefunction fitted to each group for later use. Something in the lines of:

df %>% group_by(group) %>% .... foo(splinefun(x,y))

I do not care for the original data (which contains more than group,x,y), so the return values could be a named list of functions, or anything i can reference with the group variable and get the fitted spline function. Use case is iterating over a second dataset with group and interpolation coordinate x. Anyone?

Edit

So an updated example with newData wich contains a group not included in the tibble of fitted functions:

df<-data.frame(group=c(rep(1,4),rep(2,4),rep(3,4)),
               x=c(rep(c(0,1,2,3),3)),
               y=c(0,1,2,3,0,1,4,9,0,1,8,27))

fit<-df %>% 
  group_by(group) %>% 
  summarise(fns = list(approxfun(x, y)))

newData <- data.frame(group=c(rep(1,5),rep(2,5),rep(3,5),rep(4,5)) , 
                      xval = rep(c(0,1,2,3,4),4)) %>% 
                      left_join(fit)

So the fitted power functions are now joined with the expanded set of groups, where column fns is NULL on the missing records. If i can now mutate newData with column interpolated applying the functions where fns is not NULL and NA otherwise, I would be done.

1
If you are iterating over a second dataset, after the summarise step, do a join by 'group' and then do a mutate with the splinefun column applied over the variable of interest in the sceond dataakrun

1 Answers

0
votes

We can output the function by wrapping it with list

library(tidyverse)
df %>% 
    group_by(group) %>%
    summarise(fns = list(splinefun(x, y)))

If the intention is to create a column in the original data, replace summarise with mutate. However, this will repeat the function for each row of the group


If we want to apply the functions on another dataset on the corresponding 'group', then do a join with the second dataset and apply the function stored in the first data column on the column of interest in second data using map2

df %>% 
   group_by(group) %>% 
   summarise(fns = list(splinefun(x, y))) %>% 
   left_join(df2) %>% 
   mutate(newval = map2_dbl(fns, xval, ~ .x(.y)))

Update

Based on the updated data in the OP's post

fit %>% 
  right_join(newData) %>% 
  mutate(newval = map2_dbl(fns, xval, ~ if(!is.null(.x)) .x(.y) else NA_real_))

Or create a function with possibly (from purrr) and apply

f1 <- possibly(function(x, y) x(y), otherwise = NA_real_)
fit %>% 
  right_join(newData) %>% 
  mutate(newval = map2_dbl(fns, xval, f1))

data

df2 <- data.frame(group = 1:3, xval = c(1.5, 2.5, 3.2))
newData <- data.frame(group=c(rep(1,5),rep(2,5),rep(3,5),rep(4,5)), 
                   xval = rep(c(0,1,2,3,4),4))