How to cast NA based on class of another object (input parameter)

I had some very helpful assistance with another of my functions - so here is another

I use min/max a lot with summarise. Often with na.rm = TRUE
Sometimes some of the groups when using group_by have no non-NA values and you get warnings because max/min return +/- Inf if all NA

Questions:

  1. Is there an off-the-shelf way of eliminating the warnings with blanket suppressWarnings?
  2. I end up having to test for class == POSIXct.Date and Date because using "as" does not work for those 2 classes. Is there a slicker way of casting the return value to the class of the input x?
MaxNA = function(x,na.rm = TRUE) {
  if (na.rm) {
    x<-x[!is.na(x)]
  }
  if (length(x)>0) max(x, na.rm = na.rm) else {
    if(is.POSIXct(x)) {
      as.POSIXct.Date(NA)
    } else if (is.Date(x)){
      as.Date(NA)
    } else {
       as(NA, class(x))
    }
  }
}

TodayDate = Sys.Date()

Sampledf = tibble(cat = c(1,1,1,2,2,2), date = c(rep(TodayDate,3),rep(as.Date(NA),3)))
#> Error in tibble(cat = c(1, 1, 1, 2, 2, 2), date = c(rep(TodayDate, 3), : could not find function "tibble"

summary = Sampledf %>%
  group_by(cat) %>%
  summarise(maxdate = MaxNA(date))
#> Error in Sampledf %>% group_by(cat) %>% summarise(maxdate = MaxNA(date)): could not find function "%>%"

print(summary)
#> function (object, ...) 
#> UseMethod("summary")
#> <bytecode: 0x0000014dc35edce8>
#> <environment: namespace:base>

Created on 2023-02-24 with reprex v2.0.2

Replying to own post.

You know when you make the effort to ask the question properly, the answer is clear?
I think the more elegant version of my function is as below.
But I think the 2 questions remain.

MaxNA = function(x,na.rm = TRUE) {
  if (na.rm) {
    xNotNA<-x[!is.na(x)]
  }
  if (length(xNotNA)>0) 
    max(xNotNA, na.rm = na.rm) 
  else 
    x[1]
}

your refined code doesnt handle na.rm=FALSE ; i.e. if the first if doesnt evaluate true; the next if has a problem with undefined xNotNA

  1. you can throw the whole body of the function you are defining inside the expression of a suppressWarnings if thats what you want.
myx2 <- function(x) {
  suppressWarnings({
    # normal function content
    warning("do a warn")
    x^2
  })
}

myx2(2)

I like your x[1] approach to maintaining the type; seems straightforward to me

Thank you for spotting my omission. I should have spent more time checking/testing.

New code below. Almost ashamed of how I named x2

MaxNA = function(x,na.rm = TRUE) {
  if (na.rm)
    x2<-x[!is.na(x)]
  else
    x2 <- x
  
  if (length(x2)>0) 
    max(x2, na.rm = na.rm) 
  else 
    x[1]
}

This topic was automatically closed 42 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.