Возврат списка функций с помощью dplyr - PullRequest
0 голосов
/ 16 января 2019

У меня есть data.frame с координатами x, y и переменной группировки:

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))

Я бы хотел, чтобы сплайн-функция была установлена ​​в каждой группе для последующего использования. Что-то в строках:

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

Меня не волнуют исходные данные (которые содержат больше, чем group, x, y), поэтому возвращаемые значения могут быть именованным списком функций или чем угодно, на что я могу ссылаться с помощью переменной группы и получать встроенную функцию сплайна. , Вариант использования - это итерация по второму набору данных с группой и координатой интерполяции x. Кто-нибудь?

Редактировать

Итак, обновленный пример с newData, который содержит группу, не включенную в таблицу встроенных функций:

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)

Таким образом, встроенные степенные функции теперь объединены с расширенным набором групп, где столбец fns равен NULL для отсутствующих записей. Если бы я теперь мог мутировать новые данные в столбце , интерполируя , применяя функции, в которых fns не равно NULL, а в противном случае NA, я бы сделал это.

1 Ответ

0 голосов
/ 16 января 2019

Мы можем вывести функцию, обернув ее в list

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

Если вы хотите создать столбец в исходных данных, замените summarise на mutate. Однако это будет повторять функцию для каждой строки группы


Если мы хотим применить функции к другому набору данных в соответствующей «группе», выполните объединение со вторым набором данных и примените функцию, хранящуюся в первом столбце данных, к интересующему столбцу для вторых данных, используя map2

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

Обновление

На основании обновленных данных в посте ОП

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

Или создайте функцию с possibly (из purrr) и примените

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

данные

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))
...