使用mutate时,函数在管道中不起作用

时间:2019-04-17 06:41:14

标签: 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 个答案:

答案 0 :(得分:0)

在使用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中的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))