Оператор if else с несколькими условиями и 4 исходами

Я пытаюсь классифицировать виды на основе общности. Существует 4 классификации:

  1. Редко - частота<среднее значение и относительная численность<среднее значение
  2. Иногда - частота<среднее значение и относительная численность>среднее значение
  3. Общие - частота>среднее значение и относительная численность<среднее значение
  4. Доминантный - частота > среднее и относительное обилие > среднее

Я пытаюсь создать оператор if else, чтобы добавить столбец с этими классификациями в мой фрейм данных, который выглядит как

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)

Я пробовал что-то вроде этого:

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"

Но это не работает, поскольку классифицирует все виды как «редкие». Я очень новичок в заявлениях if else, поэтому любая помощь будет оценена по достоинству.

Благодарю вас!

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
39
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Я получаю "Иногда", используя ваш код.

Ваши операторы if просматривают логические векторы, но возвращают одно значение для ВСЕХ строк, например:

df[,2] это весь столбец: 0.50 0.11 0.23 0.06 0.36 0.19

df[,2]>mean(relabund) возвращает логический вектор:

TRUE FALSE FALSE FALSE TRUE FALSE

используя &&, вы выполняете логическое сравнение двух логических векторов. Поскольку эти векторы не совпадают, вы всегда получаете false:

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

==

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

==

FALSE

Кроме того, df$Classification устанавливает для столбца одно и то же значение, т. е. работает со всем набором данных, а не построчно. Что вам нужно сделать, это выполнить векторные операции в каждой строке.

Используя dplyr, вы можете получить более понятный ответ (для некоторых!)

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")))))

Большое спасибо! Я даже не подумал о том, что эти аргументы вернули логику. Я пытаюсь начать использовать tidyverse, намного чище!

elisemillar 25.04.2022 23:18

Мы можем использовать case_when, где if находится слева от ~, а справа — значение, которое вы хотите присвоить этому условию.

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"))

Выход

  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

Данные

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))

Другие вопросы по теме