Создание объекта пользовательского класса и назначение ему методов

#r #oop

#r #ооп

Вопрос:

Я пытаюсь создать объект класса «weeknumber», который имел бы следующий формат: «2019-W05»

Кроме того, мне нужно иметь возможность использовать этот объект с операторами -. Аналогично переменные «Date» ведут себя в базе R. Например:

  • «2019-W05» 1 = «2019-W06»
  • «2019-W01» — 1 = «2018-W52»
  • «2019-W03» — «2019-W01» = 2

Мне удалось частично достичь своей цели. Это то, что я получил на данный момент:

 weeknum <- function(date){

    # Function that creates weeknumber object from a date

    weeknumber <- paste(isoyear(date), formatC(isoweek(date), width = 2, format = "d", flag = "0"), sep = "-W")
    class(weeknumber) <- c("weeknumber", class(weeknumber))
    weeknumber
}

week2date <- function(weeknumber, weekday = 4) {

    # Wrapper around ISOweek2date function from the 'ISOweek' package

    ISOweek2date(paste(weeknumber, weekday, sep = "-"))
}

" .weeknumber" <- function(x, ...) {

    # Creating a method for addition

    x <- week2date(x)   sum(...)*7

    weeknum(x)
}

"-.weeknumber" <- function(x, ...) {

    # Creating a method for subtraction

    x <- week2date(x) - sum(...)*7

    weeknum(x)
}
  

Что работает:

 > x <- weeknum("2019-01-01")

> x
[1] "2019-W01"
attr(,"class")
[1] "weeknumber" "character" 

> x   1
[1] "2019-W02"
attr(,"class")
[1] "weeknumber" "character" 

> x - 1
[1] "2018-W52"
attr(,"class")
[1] "weeknumber" "character" 
  

Работает так, как ожидалось! Единственное, что раздражает, это то, что вызов переменной также
выводит атрибуты. Есть ли способ скрыть их в распечатке по умолчанию?

Что не работает:

 > 1   x
 Error: all(is.na(weekdate) | stringr::str_detect(weekdate, kPattern)) is not TRUE 

> y <- weeknum("2019-03-01")
> y - x
 Error in as.POSIXlt.default(x) : 
  do not know how to convert 'x' to class “POSIXlt” 
  

Любая помощь приветствуется!

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

Нашел решение, как заставить работать 1 x (где x — номер недели). Не очень элегантно, но выполняет свою работу.

 " .weeknumber" <- function(...) {

    # Creating a method for addition

    vector <- c(...)

    week_index   <- which(unlist(lapply(list(...), function(x) class(x)[1]))=="weeknumber")
    week         <- vector[week_index]
    other_values <- sum(as.numeric(c(...)[-week_index]))

    x <- week2date(week)   other_values*7

    weeknum(x)

}

> x <- weeknum("2019-01-01")
> x
[1] "2019-W01"

> 5   x   1   2 - 1
[1] "2019-W08"


  

Ответ №1:

Для первой части: определите пользовательский print -метод для вашего класса:

 print.weeknumber <- function(x,...) 
  {
  attributes(x) <- NULL
  print(x)
  }