Передача пользовательской функции с условиями в dplyr :: mutate - PullRequest
0 голосов
/ 07 февраля 2020

У меня есть набор данных, подобный следующему:

 seq <- tibble(REF = c("A","C","G","T","C","G"),
        REF2 = c("A","G","G","A","C","G")) %>%
   dplyr::mutate(UP = dplyr::lag(REF, n=1),
                 DOWN = dplyr::lead(REF, n=1))

# A tibble: 6 x 4
#  REF   REF2  UP    DOWN 
#  <chr> <chr> <chr> <chr>
#1 A     A     NA    C    
#2 C     G     A     G    
#3 G     G     C     T    
#4 T     A     G     C    
#5 C     C     T     G    
#6 G     G     C     NA 

И я хотел бы изменить некоторые из этих букв (между AT и G- C) выше, когда содержимое столбцов REF и REF2 отличается , Для этого я написал небольшую функцию и запустил ее с dplyr::mutate следующим образом:

switch_strand <- function(base) {
  if (base=="A") return ("T")
  else if (base=="T") return ("A")
  else if (base=="G") return ("C")
  else if (base=="C") return ("G")
  else if (is.na(base)) return (NA) 
  else stop("Error, base does not exist")
}

seq %>% dplyr::mutate(UP = ifelse(REF!=REF2,switch_strand(UP),UP),
                      DOWN = ifelse(REF!=REF2,switch_strand(DOWN),DOWN))

Но получена следующая ошибка:

Ошибка в if ( base == "A") return ("T") else if (base == "T") return ("A") else if (base ==: пропущенное значение, где требуется TRUE / FALSE Дополнительно: предупреждающее сообщение: In if (base == "A") return ("T") else if (base == "T") return ("A") else if (base ==: условие имеет длину> 1 и только первый элемент будет использоваться

Что я не понимаю, разве значения, вызываемые в dplyr::mutate, не используются построчно? Приведенная выше функция работает, как и ожидалось, если вводятся отдельные буквы, но я не понимаю почему в качестве аргумента вводятся полные столбцы. Как это можно исправить?

Ожидаемый результат:

# A tibble: 6 x 4
#  REF   REF2  UP    DOWN 
#  <chr> <chr> <chr> <chr>
#1 A     A     NA    C    
#2 C     G     T     C    
#3 G     G     C     T    
#4 T     A     C     G    
#5 C     C     T     G    
#6 G     G     C     NA

РЕДАКТИРОВАТЬ : я исправил switch_base функция, поэтому она должна возвращать NA, если base равен NA, но, похоже, в этом случае происходит сбой ... это может быть связано с этим.

Ответы [ 2 ]

3 голосов
/ 07 февраля 2020

перед дополнительной мутацией передайте дополнительную функцию "dplyr :: rowwise ()":

seq %>% dplyr::rowwise() %>% dplyr::mutate(UP = ifelse(REF!=REF2,switch_strand(UP),UP),
                      DOWN = ifelse(REF!=REF2,switch_strand(DOWN),DOWN))
1 голос
/ 07 февраля 2020

Как уже упоминалось в комментариях if / else не векторизовано и в настоящее время функция работает только для скалярного ввода, а не для векторов. Поскольку вы используете dplyr, мы можем использовать case_when, чтобы сделать его векторизованным.

library(dplyr)

switch_strand <- function(base) {
   case_when(base == "A" ~ "T", 
             base=="T" ~ "A", 
             base=="G" ~ "C", 
             base=="C" ~ "G")

}

и тогда попытка кода будет работать нормально

seq %>% 
  mutate(UP = ifelse(REF!=REF2,switch_strand(UP),UP),
         DOWN = ifelse(REF!=REF2,switch_strand(DOWN),DOWN))

#  REF   REF2  UP    DOWN 
#  <chr> <chr> <chr> <chr>
#1 A     A     NA    C    
#2 C     G     T     C    
#3 G     G     C     T    
#4 T     A     C     G    
#5 C     C     T     G    
#6 G     G     C     NA   
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...