1

I still get errors with the following code. Could anyone help me please? I need to find the median number of a set of three numbers.

find_median = function(a, b, c){
    if(a > b){
      if(a > c){
      if(c > b){
        return(b)}
      else{return(c)}
   }
   else {return(a)}
  }
  else if(b > a){
    if(b > c){
      if(c > a){
        return(c)}
      else {return(a)}
    }
    else {return(b)}
  }
  else if(c > a){
      if(c > b){
        if(a > b){
          return(a)}
        else {return(b)}
     }
      else {return(c)}
  }
}
beaker
  • 16,331
  • 3
  • 32
  • 49
LearningR
  • 21
  • 2
  • Provide a sample of your data. Does "the set of 3 ones" mean that `a`, `b`, and `c` are all 1? If the values are equal, then the median is the repeated value. If `x` is a vector of 3 different values (e.g. `x <- sample.int(100, 3)`, then `sort(x)[2]` is the median`. – dcarlson Sep 28 '22 at 02:45
  • Hmmm. Using only `if`s, copy @Museful [permutations](https://stackoverflow.com/questions/11095992/generating-all-distinct-permutations-of-a-list-in-r), then `my3 <- matrix(c(1:3)[permutations(3)], ncol = 3)` to see the range that you'll be dealing with, then `if (my3[6,1] >= my3[6,2] & my3[6,2] >= my3[6,3]) print(my3[6,2]) [1] 2`, get them printing 2 for all conditions. print is your return, else between each, then substitute a, b, c back in for the matrix notation. I find truth tables devilishly difficult, and in a world of three, `sort(x)[2]`, but `if`can do it. Welcome to Stackoverflow. – Chris Sep 28 '22 at 03:19
  • I think you are almost there: find_median = function(a, b, c) { if (a > b) { if (a > c) { if (c > b) { return(b)} # should be c else{ return(c)} # should be b The rest of the returns look good – Isaiah Sep 28 '22 at 13:34

2 Answers2

0

Just expanding on my comment, but the hardest part of truth tables (or any function really) is accounting for all the variations of inputs that might present. Often this is handled by error checking, essentially saying, not designed to do that or work with that. Here, the question is what's the number in the middle, so taking the elegant permutations by @Museful :

permutations <- function(n){
    if(n==1){
        return(matrix(1))
    } else {
        sp <- permutations(n-1)
        p <- nrow(sp)
        A <- matrix(nrow=n*p,ncol=n)
        for(i in 1:n){
            A[(i-1)*p+1:p,] <- cbind(i,sp+(sp>=i))
        }
        return(A)
    }
}

my3<-matrix(c(1:3)[permutations(3)], ncol = 3)
> my3
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    1    3    2
[3,]    2    1    3
[4,]    2    3    1
[5,]    3    1    2
[6,]    3    2    1

# all possibles now known

if (my3[6,1] >= my3[6,2] & my3[6,2] >= my3[6,3]) print(my3[6,2])
[1] 2
> if (my3[5,1] >= my3[5,2] & my3[5,2] <= my3[5,3]) print(my3[5,3])
[1] 2
> if (my3[4,1] >= my3[4,3] & my3[4,1] <= my3[4,2]) print(my3[4,1])
[1] 2
> if (my3[3,1] >= my3[3,2] & my3[3,2] <= my3[3,3]) print(my3[3,1])
[1] 2
> if (my3[2,1] <= my3[2,2] & my3[2,2] >= my3[2,3]) print(my3[2,3])
[1] 2
> if (my3[1,1] <= my3[1,2] & my3[1,2] <= my3[1,3]) print(my3[1,2])
[1] 2

Now substitute the [,1], [,2], [,3], to a,b,c; print to return, and else between...

Chris
  • 1,647
  • 1
  • 18
  • 25
0

Here is another approach that uses if statements to sort the values like the code in the original question but more compact. Getting the nested "{}" is the real challenge. We can order the values by making three comparisons a<b, a<c, and b<c. That makes it a bit easier to follow the code:

find_median = function(a, b, c) {
ab <- a < b
ac <- a < c
bc <- b < c

if (ab) { 
    if (ac) { 
        if (bc) {return(b) 
        } else return(c)
    } else return(a)
} else if (ac) { return(a)
    } else if (bc) { return(c)
    } else return(b)
}

Now test it:

a <- sample.int(50, 1)
b <- sample.int(50, 1)
c <- sample.int(50, 1) 
a; b; c
# [1] 25
# [1] 10
# [1] 36
find_median(a, b, c)
# [1] 25
dcarlson
  • 10,936
  • 2
  • 15
  • 18