#r #tidyr #tidy
#r #tidyr #привести в порядок
Вопрос:
У меня есть список имен и назначенные пороговые значения для этих имен, чтобы определить, присвоено ли мне подходящее имя.
Вы можете воссоздать тестовый набор данных, используя это:
df <- data.frame(level1 = c("Eukaryota","Eukaryota","Eukaryota","Eukaryota","Eukaryota"),
level2=c("Opisthokonta","Alveolata","Opisthokonta","Alveolata","Alveolata"),
level3=c("Fungi","Ciliophora","Fungi","Ciliophora","Dinoflagellata"),
level4=c("Basidiomycota","Spirotrichea","Basidiomycota","Spirotrichea","Dinophyceae"),
value = c("100;5;4;2", "100;100;100;100", "100;80;60;50", "90;50;40;40","100;80;20;0"))
Я хотел бы использовать tidy verse mutate()
и case_when()
, чтобы найти таксономический уровень, который превышает подходящий порог. Таким образом, приведенный ниже оператор tidy verse разбивает пороговые значения, а затем пытается это сделать.
Мои бутылочные горлышки
- Используя оператор
case_when()
вместоifelse()
— может быть, более целесообразно использовать ifelse()?? - Я не могу понять, как заполнить новый столбец с именем Name_updated с объединенным level1-levelX. Прямо сейчас unite() не подходит, поскольку это имеет отношение к целым наборам данных. На самом деле у меня намного больше столбцов, поэтому делать это без синтаксиса tidy verse
level1:level3
было бы болезненно!
df_updated <- df %>%
separate(value, c("threshold1","threshold2", "threshold3", "threshold4"), sep =";") %>%
mutate(Name_updated = case_when(
threshold4 >= 50 ~ unite(level1:level4, sep = ";"), #Fill with all taxonomic names to level4
threshold4 < 50 amp; threshold3 >= 60 ~ unite(level1:level3, sep = ";"), #If last threshold is <50, only fill with taxonomic names to level3
threshold4 < 50 amp; threshold3 < 60 amp; threshold2 >= 50 ~ unite(level1:level2, sep = ";"), #If thresholds for level 3 and 4 are below, fill only level1;level2
TRUE ~ level1)) %>% #Otherwise fill with only level 1
data.frame
Желаемый результат
> df_updated$Name_updated
# Output of this new list:
Eukaryota
Eukaryota;Alveolata;Ciliophora;Spirotrichea
Eukaryota;Opisthokonta;Fungi;Basidiomycota
Eukaryota;Alveolata
Eukaryota;Alveolata
Желательным следующим шагом является написание функции, которая позволяет пользователю указывать пороговые значения, которые используются в скрипте. Итак, мне действительно нужно сделать проверку / определение того, какой порог проходит, надежным.
Ответ №1:
Проблема заключается в unite
а также type
в separate
столбце ed. По умолчанию, convert = FALSE
и это был бы character
столбец класса
library(dplyr)
library(tidyr)
library(purrr)
library(stringr)
df %>%
type.convert(as.is = TRUE) %>%
separate(value, c("threshold1","threshold2",
"threshold3", "threshold4"), sep =";", convert = TRUE) %>%
mutate(Name_updated =
case_when(
threshold4 >= 50 ~
select(., starts_with('level')) %>%
reduce(str_c, sep=";"),
threshold4 < 50 amp; threshold3 >= 60 ~
select(., level1:level3) %>%
reduce(str_c, sep=";"),
threshold4 < 50 amp; threshold3 < 60 amp; threshold2 >= 50 ~
select(., level1:level2) %>%
reduce(str_c, sep=";"),
TRUE ~ level1))
# level1 level2 level3 level4 threshold1 threshold2 threshold3 threshold4
#1 Eukaryota Opisthokonta Fungi Basidiomycota 100 5 4 2
#2 Eukaryota Alveolata Ciliophora Spirotrichea 100 100 100 100
#3 Eukaryota Opisthokonta Fungi Basidiomycota 100 80 60 50
#4 Eukaryota Alveolata Ciliophora Spirotrichea 90 50 40 40
#5 Eukaryota Alveolata Dinoflagellata Dinophyceae 100 80 20 0
# Name_updated
#1 Eukaryota
#2 Eukaryota;Alveolata;Ciliophora;Spirotrichea
#3 Eukaryota;Opisthokonta;Fungi;Basidiomycota
#4 Eukaryota;Alveolata
#5 Eukaryota;Alveolata
Комментарии:
1. Я все еще получаю сообщение о том, что
mutate()
ввод является фактором, а не символьным вектором2. и следующий вопрос, почему бы и нет
library(tidyverse)
? вместо 3 отдельных?3. @shu251 это может быть связано с тем, что вы используете другую версию R. Я использовал > 4,00, где
stringsAsFactors = FALSE
вdata.frame
4. ах да! поскольку я все еще использую 3.6.1 для некоторых проектов, это моя новая «любимая» ошибка, с которой приходится иметь дело при переходе туда и обратно. Спасибо!