Я пытаюсь классифицировать виды на основе общности. Существует 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, поэтому любая помощь будет оценена по достоинству.
Благодарю вас!
Я получаю "Иногда", используя ваш код.
Ваши операторы 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")))))
Мы можем использовать 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))
Большое спасибо! Я даже не подумал о том, что эти аргументы вернули логику. Я пытаюсь начать использовать tidyverse, намного чище!