R - failing to detect column with max value

Viewed 57

I have a dataset with three columns (A, B, C). Each corresponds to the amount of Apple, Bananas or Carrots a child eats per day.

For each day I want to log the most consumed food (i.e., column with the highest value). If value between columns is equal (e.g., 1 apple and 1 banana), then apply the following rank. Apple > Banana > Carrot, whereby if a child eats 1 Apple and 1 Banana, the log will show Apple.

I've tried implementing this in R using by classifying pairs of if_else statements using case_when(). However, it does not return the correct result. For example, the final row should be classified as Apple, not carrot. I'm not sure what I'm doing wrong.

Note: Please provide a Tidyverse implemented solution rather than base R as this is how I'm learning R. Using a different function to the one I tried is fine but if possible, please explain why my attempt doesn't work so I can learn.

library(tidyverse)

A <- c(1,1,3,3)
B <- c(2,3,1,1)
C <- c(1,1,1,2)
df <- data.frame(A,B,C)

top_food <- df %>% 
  mutate(highest = case_when(
    C > B ~ "carrot", # if carrot > banana
    C > A ~ "carrot", # if carrot > apple 
    B > A ~ "banana", # if banana > apple 
    B >= A ~ "banana", # if banana >= carrot
    A >= B ~ "apple", # if apple  >= banana
    A >= C ~ "apple" # if apple >= carrot
  )) 

> | A | B | C | HIGHEST |  |
> | 1 | 2 | 1 | banana  |  |
> | 1 | 3 | 1 | banana  |  |
> | 3 | 1 | 1 | apple   |  |
>   3 | 1 | 2 | carrot  |  |
1 Answers

Allow me to modify your data so we actually have ties on which we can see your rule of precedence (Apple > Banana > Carrot) in action. Also, I'll use somewhat more informative column names.

Apples <- c(1,1,3,3,4,4,1)
Bananas <- c(2,3,1,1,4,1,4)
Carrots <- c(1,1,1,2,1,4,4)
df <- data.frame(Apples,Bananas,Carrots)

I'll take the liberty of using base R. Specifically, I'll treat df as a matrix and apply the which.max() function to each row.

result <- apply(as.matrix(df),1,which.max)

This correctly treats your rule of precedence, because (1) which.max() returns the index of the first maximum it encounters (see ?which.max) and (2) df is column-ordered in the correct order of precedence.

Here is the result:

data.frame(df,Max=colnames(df)[result])

  Apples Bananas Carrots     Max
1      1       2       1 Bananas
2      1       3       1 Bananas
3      3       1       1  Apples
4      3       1       2  Apples
5      4       4       1  Apples
6      4       1       4  Apples
7      1       4       4 Bananas
Related