Home > other >  If else statement with multiple conditions and 4 outcomes
If else statement with multiple conditions and 4 outcomes

Time:04-23

I am trying to classify species based on commonness. There are 4 classifications:

  1. Rare - frequency<mean & relative abundance<mean
  2. Occasional - frequency<mean & relative abundance>mean
  3. Common - frequency>mean & relative abundance<mean
  4. Dominant - frequency>mean & relative abundance>mean

I am trying to create an if else statement to add a column with these classifications to my data frame which looks like

species <- c("a", "b", "c", "d", "e", "f")
relabund <- c(.5, .11, .23, .06, .36, .19) #relative abundance
freq <- c(6, 3, 20, 2, 11, 4) #number of sites species occurs at
df = data.frame(species, relabund, freq)

I've tried something like this:

if (df[,2]>mean(relabund) && df[,3]>mean(freq)) {
    df$Classification = "Dominant"
  } else if (df[,2]<mean(relabund) && df[,3]<mean(freq)) {
    df$Classification = "Rare"
  } else if (df[,2]<mean(relabund) && df[,3]>mean(freq)) {
    df$Classification = "Common"
  } else 
    df$Classification = "Occasional"

But this doesn't work as it classifies all species as "Rare". I'm very new to if else statements so any help would be appreciated.

Thank you!

CodePudding user response:

I get "Occaisonal" using your code.

Your if statements are looking at logical vectors, but returning one value for ALL rows, for example:

df[,2] is the whole column: 0.50 0.11 0.23 0.06 0.36 0.19

df[,2]>mean(relabund) returns a logical vector of:

TRUE FALSE FALSE FALSE TRUE FALSE

by using && you are performing a logical comparison to two logical vectors. As these vectors aren't the same, you always get false:

df[,2]>mean(relabund) && df[,3]>mean(freq)

==

c(TRUE, FALSE, FALSE, FALSE, TRUE, FALSE) && c(FALSE, FALSE, TRUE, FALSE, TRUE, FALSE)

==

FALSE

Also, df$Classification sets the column to be the same value, i.e. it's working on the whole dataset rather than row by row. What you need to do it perform vector operations on each row.

Using dplyr you can get an easier to read answer (for some!)

library(tidyverse)

species <- c("a", "b", "c", "d", "e", "f")
relabund <- c(.5, .11, .23, .06, .36, .19) #relative abundance
freq <- c(6, 3, 20, 2, 11, 4) #number of sites species occurs at
df = data.frame(species, relabund, freq)

df %>% 
  mutate(classify = 
           ifelse(freq < mean(freq) & relabund < mean(relabund),
                  "Rare",
           ifelse(freq < mean(freq) & relabund > mean(relabund),
                  "Occaisonal",
           ifelse(freq > mean(freq) & relabund < mean(relabund),
                 "Common",
           ifelse(freq > mean(freq) & relabund > mean(relabund),
                 "Dominant",
                 "ERROR")))))

CodePudding user response:

We can use case_when, where the if is on the left side of ~ and to the right is the value you want to assign to that condition.

library(tidyverse)

df %>% 
  mutate(classify = case_when(freq < mean(freq) & relabund < mean(relabund) ~ "Rare",
                              freq < mean(freq) & relabund > mean(relabund) ~ "Occaisonal",
                              freq > mean(freq) & relabund < mean(relabund) ~ "Common",
                              freq > mean(freq) & relabund > mean(relabund) ~ "Dominant",
                              TRUE ~ "ERROR"))

Output

  species relabund freq   classify
1       a     0.50    6 Occaisonal
2       b     0.11    3       Rare
3       c     0.23   20     Common
4       d     0.06    2       Rare
5       e     0.36   11   Dominant
6       f     0.19    4       Rare

Data

df <- structure(list(species = c("a", "b", "c", "d", "e", "f"), relabund = c(0.5, 
0.11, 0.23, 0.06, 0.36, 0.19), freq = c(6, 3, 20, 2, 11, 4)), class = "data.frame", row.names = c(NA, 
-6L))
  • Related