Оператор 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, поэтому любая помощь будет оценена по достоинству.

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

3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
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))

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