Заполнить столбец с помощью unite(), используя оператор mutate и case_when() в R, привести в порядок стих

#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 разбивает пороговые значения, а затем пытается это сделать.
Мои бутылочные горлышки

  1. Используя оператор case_when() вместо ifelse() — может быть, более целесообразно использовать ifelse()??
  2. Я не могу понять, как заполнить новый столбец с именем 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 для некоторых проектов, это моя новая «любимая» ошибка, с которой приходится иметь дело при переходе туда и обратно. Спасибо!