-2

I am having a problems with getting na.rm to behave how I want to. I am practicing writing functions and currently writing a function for mean. My test vector is t <- c(12,14, NA, 1) my two test are

  my.mean(t)
  my.mean(t, na.rm=TRUE) 

my first function passed test one but was still returned NA for test 2 (it should be 9)

my.mean <- function(x, na.rm) {
 stopifnot(is.numeric(x))
 answer <- sum(x)/length(x)
 return(answer)
}

Then I changed the function which worked for the second test and returned 9 but for the first test returned Error in my.mean(t.2) : argument "na.rm" is missing, with no default

my.mean <- function(x, na.rm) {
    stopifnot(is.numeric(x))
    if na.rm=TRUE {na.omit()}
    answer <- sum(x)/length(x)
    return(answer)
}
Thomas Guillerme
  • 1,747
  • 4
  • 16
  • 23
snowy
  • 17
  • 2
  • 1
    Your second function isn't valid at all, let alone able to give an incorrect answer. You're missing brackets for the `if()` , don't put any value for `na.omit()` which needs to be called like `na.omit(x)`, and are using `=` to test equality `na.rm=TRUE` when you need the double `==` instead. Please check again what you are working with. – thelatemail Nov 20 '18 at 03:55

2 Answers2

1

you forgot to assign a default value for na.rm in your second function. A good practice should be to add a default value (e.g. TRUE). Furthermore, note that your logical should be == rather than = (and in brackets) and that na.omit should be applied on x and returned:

my.mean <- function(x, na.rm = TRUE) {
    stopifnot(is.numeric(x))
    if (na.rm==TRUE) {x <- na.omit(x)}
    answer <- sum(x)/length(x)
    return(answer)
}

If you want the default to be used within the function, you can use the missing() function within your if statement:

my.mean <- function(x, na.rm) {
    stopifnot(is.numeric(x))
    if(!missing(na.rm) && na.rm == TRUE) {
        x <- na.omit(x)
    }
    answer <- sum(x)/length(x)
    return(answer)
}

Note that in this case, using na.rm = FALSE should return NA because sum(t) = NA:

my.mean(t)
#[1] NA
my.mean(t, na.rm = TRUE)
#[1] 9
my.mean(t, na.rm = FALSE)
#[1] NA
Thomas Guillerme
  • 1,747
  • 4
  • 16
  • 23
  • 1
    I want the default of the function to be `na.rm=FALSE` so i just didn't but the `TRUE` in the first function you wrote. I was forgetting to put `==` in the `if` statement! I got it to work thank you! – snowy Nov 20 '18 at 04:42
0

The error you're getting simply states that you have defined an argument (na.rm) without giving it a default setting. In such a case, if you don't explicitly give the argument a setting in your call, the function fails.

To give your argument a default, do something like:

my.mean<-function(x, na.rm=FALSE) ...

This will make the default FALSE.

iod
  • 7,412
  • 2
  • 17
  • 36