代码之家  ›  专栏  ›  技术社区  ›  Hector Haffenden

作用域-tible中的函数

r
  •  0
  • Hector Haffenden  · 技术社区  · 6 年前

    在本例中,我将使用tidyverse的tibble()来存储函数。

    cost.matrix <- tibble(cost = c(function(x){0}, function(x){0}, function(x){NA}, function(x){x^2}, function(x){(3/2)*x},  function(x){x}),
                               flow = c(function(alpha,beta){(1/2)-alpha},function(alpha,beta){(1/2)-beta},  function(alpha,beta){NA}, function(alpha,beta){alpha},  function(alpha,beta){beta},
                                        function(alpha, beta){1-alpha-beta}))
    

    例如,

    cost.matrix$cost
    # and
    cost.matrix$flow
    

    将列出所有函数。

    function(x){x^2}  
    # and
    function(alpha, beta){1-alpha-beta}
    # The new function will be
    function(alpha, beta){(1-alpha-beta)^2}
    

    为此,我使用了一个简单的for循环(如果有人有更好的建议,请告诉我,在矢量化以下组合函数时遇到了问题),并在每一行上使用了此组合函数:

    Composite <- function(f,g) function(...) f(g(...))
    

    所以现在我们的代码如下所示(我们创建一个新列,然后使用for循环用cost和flow列的组合替换相应的元素):

    data <- cost.matrix %>%
      mutate(cost.flow.comp = cost)
    for (i in 1:nrow(data)){
      a <- data$cost[[i]]
      b <- data$flow[[i]]
      want <- Composite(a,b)
      data$cost.flow.comp[[i]] <- want
    }
    

    问题

    如果我们运行以下代码,现在应该得到25:

    data$cost.flow.comp[[4]](5,2)
    

    function(x){x^2}
    # and
    function(alpha, beta){alpha}
    

    但是我们得到-6,因为成本流量公司列实际上已分配给以下函数的组合:

    function(x){x}
    function(alpha,beta){1-alpha-beta}
    

    解决方案 我找到了一个解决这个问题的方法,就是每次在for循环中,在编写完函数之后调用它。例如(我们在分配合成后调用want函数):

    data <- cost.matrix %>%
      mutate(cost.flow.comp = cost)
    for (i in 1:nrow(data)){
      a <- data$cost[[i]]
      b <- data$flow[[i]]
      want <- Composite(a,b)
      want(1,1)
      data$cost.flow.comp[[i]] <- want
    }
    

    问题

    为了读者的兴趣,这种方法的用例是用流和成本表示一个网络。想和他们一起做手术。

    0 回复  |  直到 6 年前
        1
  •  2
  •   user2554330    6 年前

    这是一个懒惰的评估而不是范围界定的问题。问题是 Composite f g ,它只是创建一个函数,将这些名称作为其主体的一部分。它们的值在第一次调用之前是不固定的。要解释-6,很难找出值的真正来源,但解决方法很简单:更改 混合成的

    Composite <- function(f, g) {
      force(f)
      force(g)
      function(...) f(g(...))
    }
    

    然后你的原版就可以了。

    > data <- cost.matrix %>%
    +   mutate(cost.flow.comp = cost)
    > for (i in 1:nrow(data)){
    +   a <- data$cost[[i]]
    +   b <- data$flow[[i]]
    +   want <- Composite(a,b)
    +   data$cost.flow.comp[[i]] <- want
    + }
    > data$cost.flow.comp[[4]](5,2)
    [1] 25
    

    顺便说一下,我想有一种更实用的方法来创建 cost.flow.comp tidyverse 什么东西。我会用 mapply ,即。

    data$new.column <- mapply(Composite, data$cost, data$flow)