2017-04-07 29 views
2

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

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 
下面

是输出:

V1 V2 V3 val val2 val3 
    1 2 3 6 12 45 
    4 5 6 15 12 45 
    7 8 9 24 12 45 
+0

“不工作”改变OP的功能是不是一个很好的问题描述。 –

+0

您能否显示您的预期输出 – akrun

+0

akrun,我期望val2和val3与val相同。 – oneko

回答

1

我们可以做到这一点,而无需使用rowwise

library(dplyr) 
as.data.frame(m) %>% 
     rowwise() %>% 
     mutate(val = calc(V1, V2, V3), 
       val2 = calc2(c(V1, V2, V3)), 
       val3 = calc3(list(V1, V2, V3))) 
# A tibble: 3 × 6 
#  V1 V2 V3 val val2 val3 
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 
#1  1  2  3  6  6  6 
#2  4  5  6 15 15 15 
#3  7  8  9 24 24 24 
+1

非常感谢akrun,这是我想要的。 – oneko

5

这什么都没有做与dplyr/mutate。你根本没有正确的矢量化。我们来看看calc2calc3作为输入,我们可以吗?

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

calc3x更有意义,除非你然后unlist它;在那之后,x是和上面一样,然后你sum的所有元素:sum(x) = 45

calc2本质上不是挽救,但你可以通过向量化修复calc3

calc3 = function (x) { 
    Reduce(`+`, x) 
} 

最后,你

calc = function (...) { 
    Reduce(`+`, list(...)) 
} 

使用方法:可以通过使用...参数获得最佳的calccalc3

as.data.frame(m) %>% mutate(v = calc(V1, V2, V3)) 
+0

变异函数需要被矢量化。第一个功能符合这个标准,而其他功能不符合。 –

+0

谢谢。现在我明白这是怎么错了。 – oneko