общая полиморфная функция c, основанная на переданных аргументах - PullRequest
0 голосов
/ 07 февраля 2020

Я ищу метод (возможно, S3-программирование), который позволяет этой функции выбирать метод на основе переданных аргументов. Я думал, что при определении класса S3 функция выберет правильный метод, но я заметил, что группа аргументов не выполняет класс объекта и не может определить его как есть. Как я могу создать логику этого полиморфизма c?

library(dplyr)
library(purrr)

sample <- data.frame(
  gp = c("a", "a", "b"),
  claims = c(30, 23, 23),
  workers = c(265, 354, 124),
  DY = c(0, 1, 0)
)

# generic IBNR function

FC_IBNR_TOT <- function(
  claims,
  ...
){
  library(dplyr)

  UseMethod("FC_IBNR_TOT", claims)
}

FC_IBNR_TOT.default <- function(
  claims,
  workers,
  ...
){

  if_else(sum(workers) == 0, 0, sum(claims) / sum(workers) * 12)
}

FC_IBNR_TOT.simple <- function(
  claims,
  workers,
  DY, # develoment year
  FDA = 1.035,
  ...
){

  if_else(
    sum(workers) == 0, 
    0, 
    sum(
      claims * 
        if_else(
          DY == 0, 
          FDA,
          1
        )
    )/ sum(workers) * 12 
  )
}

expected <- sample %>% 
  group_by(
    gp
  ) %>% 
  summarise(
    frec_1 = FC_IBNR_TOT.default(
      claims, workers
    ),
    frec_2 = FC_IBNR_TOT.simple(
      claims, workers, DY
    )
  )

expected

desired <- sample %>% 
  group_by(
    gp
  ) %>% 
  summarise(
    frec_1 = FC_IBNR_TOT(
      claims = claims, workers = workers
    ),
    frec_2 = FC_IBNR_TOT(
      claims = claims, workers = workers, DY = DY
    )
  )

desired

Обратите внимание, что нужный код всегда указывает на FC_IBNR_TOT.default. Мне нужно вызвать функцию как ее обобщенное имя c имя FC_IBNR_TOT (не FC_IBNR_TOT.default ни FC_IBNR_TOT.simple)

1 Ответ

0 голосов
/ 07 февраля 2020

Вы должны отправить его так. Тем не менее, все еще существует проблема с summaze (). Но я не мог решить это.

library(dplyr)
library(purrr)

sample <- data.frame(
  gp = c("a", "a", "b"),
  claims = c(30, 23, 23),
  workers = c(265, 354, 124),
  DY = c(0, 1, 0)
)


FC_IBNR_TOT <- function(claims, workers, DY=NULL, FDA=1.035, ...) {
  if (is.null(DY)) {
    ifelse(sum(workers) == 0, 0, sum(claims) / sum(workers) * 12)
  } else {
    ifelse(sum(workers) == 0,
                   0,
                   sum(claims * ifelse(DY == 0, FDA, 1)) / sum(workers) * 12)
  }
}

desired <- sample %>%
  group_by(gp) %>%
  summarise(frec_1 = FC_IBNR_TOT(claims, workers),
            frec_2 = FC_IBNR_TOT(claims, workers, DY))
desired
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...