使用mutate的自定义函数不起作用

one*_*eko 2 r dplyr

某些自定义函数在mutate中不起作用.你能解释为什么calc2和calc3不起作用,以及如何解决它们才能正常工作?

    library(dplyr)
    m <- matrix(c(1,2,3,4,5,6,7,8,9), nrow = 3, byrow = T)        

    calc <- function(x1,x2,x3){ #scalar
      return(x1 + x2 + x3)
    }

    calc2 <- function(x){ #vector
      return(x[1] + x[2] + x[3])
    }

    calc3 <- function(x){ #list
      x <- unlist(x)
      return(sum(x))
    }

    as.data.frame(m) %>% 
      mutate(val  = calc(V1,V2,V3), #OK
             val2 = calc2(c(V1,V2,V3) ), #NG
             val3 = calc3(list(V1,V2,V3))) #NG
Run Code Online (Sandbox Code Playgroud)

以下是输出:

    V1 V2 V3 val val2 val3
    1  2  3   6   12   45
    4  5  6  15   12   45
    7  8  9  24   12   45
Run Code Online (Sandbox Code Playgroud)

akr*_*run 6

我们可以在不改变 OP 功能的情况下使用rowwise

\n\n
library(dplyr)\nas.data.frame(m) %>%\n         rowwise() %>%\n         mutate(val = calc(V1, V2, V3), \n                val2 = calc2(c(V1, V2, V3)),\n                val3 = calc3(list(V1, V2, V3)))\n# A tibble: 3 \xc3\x97 6\n#     V1    V2    V3   val  val2  val3\n#  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>\n#1     1     2     3     6     6     6\n#2     4     5     6    15    15    15\n#3     7     8     9    24    24    24\n
Run Code Online (Sandbox Code Playgroud)\n

  • 谢谢 akrun,这正是我想要的答案。 (2认同)

Kon*_*lph 5

这与dplyr /无关mutate.你根本就没有正确的矢量化.让我们检查什么calc2,calc3得到输入,我们呢?

calc2,x = c(1L, 4L, 7L, 2L, 5L, 8L, 3L, 6L, 9L).也就是说,所有元素都连接成一个向量.然后你添加前三个:1 + 4 + 7 = 12.

calc3,x更有意义,除了你那么unlist; 之后,x与上面相同,然后你sum所有的元素:sum(x)= 45.

calc2基本上不可挽救但你可以calc3通过矢量化修复:

calc3 = function (x) {
    Reduce(`+`, x)
}
Run Code Online (Sandbox Code Playgroud)

最后,你可以得到最好的calccalc3使用...参数:

calc = function (...) {
    Reduce(`+`, list(...))
}
Run Code Online (Sandbox Code Playgroud)

用法:

as.data.frame(m) %>% mutate(v = calc(V1, V2, V3))
Run Code Online (Sandbox Code Playgroud)