функция не работает в конвейере при использовании mutate

#r #tidyverse

#r #tidyverse

Вопрос:

Моя функция работает автономно, но отказывается работать в конвейере. Что-то не так с моим синтаксисом:

 library(tidyverse)


phase1_function <- function(a1, a2, a3, a4) {

  if(any(is.na(a1), is.na(a2), is.na(a3), is.na(a4))){
    return("")  }

  if(a4 < a3){
    if(a3 < a2){
      if(a2 < a1) {"phase_1"}
    } } else {""}


}

# This works
phase1_function(1, 2, 3, NA)
phase1_function(31, 30, 29, 28)



x <- c(1:31)

# This refuses to work
data.frame(x = x) %>% 
  mutate(x1 = Hmisc::Lag(x),
           x2 = Hmisc::Lag(x1),
           x3 = Hmisc::Lag(x2)) %>%

  mutate(x4 = phase1_function(x, x1, x2, x3))
 

Пожалуйста, не могли бы вы помочь мне с моим синтаксисом

Ответ №1:

Когда вы используете mutate его, он передает весь столбец в функцию, следовательно, он возвращает одно и то же значение для всего столбца. Это эквивалентно

 phase1_function(c(1, 2), c(2, 1), c(3, 4), c(NA, 1))
#[1] ""
 

Обратите внимание, что она возвращает только одно значение в качестве выходных данных.

Вам нужно передать значения rowwise в них

 library(tidyverse)

data.frame(x = x) %>% 
   mutate(x1 = Hmisc::Lag(x),
          x2 = Hmisc::Lag(x1),
          x3 = Hmisc::Lag(x2)) %>%
   rowwise() %>%
  mutate(x4 = phase1_function(x, x1, x2, x3))

# A tibble: 31 x 5
#       x    x1    x2    x3 x4     
#   <int> <int> <int> <int> <chr>  
# 1     1    NA    NA    NA ""     
# 2     2     1    NA    NA ""     
# 3     3     2     1    NA ""     
# 4     4     3     2     1 phase_1
# 5     5     4     3     2 phase_1
# 6     6     5     4     3 phase_1
# 7     7     6     5     4 phase_1
# 8     8     7     6     5 phase_1
# 9     9     8     7     6 phase_1
#10    10     9     8     7 phase_1
# … with 21 more rows
 

Если вы хотите избежать rowwise , другой альтернативой является использование pmap from purrr

 data.frame(x = x) %>%
   mutate(x1 = Hmisc::Lag(x),
          x2 = Hmisc::Lag(x1),
          x3 = Hmisc::Lag(x2)) %>%
   mutate(x4 = pmap(list(x, x1, x2, x3), phase1_function))