代码之家  ›  专栏  ›  技术社区  ›  J. Mini

为什么Advanced R会声称您不能提供不随映射而变化的参数?

  •  0
  • J. Mini  · 技术社区  · 5 年前

    《高级R》的作者当然比我更了解R。然而 Section 9.4.5 包含以下声明:

    Map() 矢量化所有参数,因此不能提供不变的参数。

    但这显然是错误的。例如,我可以轻松地编写以下内容:

    > Map(function(x,y) x+y,1:3,runif(1))
    [[1]]
    [1] 1.224857
    
    [[2]]
    [1] 2.224857
    
    [[3]]
    [1] 3.224857
    

    事实上,同样的功能也存在于作者自己的作品中 purrr:map 功能:

    purrr::map(1:3,function(x,y) x+y,runif(1))
    [[1]]
    [1] 1.729889
    
    [[2]]
    [1] 2.729889
    
    [[3]]
    [1] 3.729889
    

    那么作者可能在谈论什么呢?我有种感觉,我只是在误读,这一猜测由于 section 9.2.3 在中展示相同的功能 purrr::map :

    plus <- function(x, y) x + y
    
    x <- c(0, 0, 0, 0)
    map_dbl(x, plus, runif(1))
    #> [1] 0.0625 0.0625 0.0625 0.0625
    map_dbl(x, ~ plus(.x, runif(1)))
    #> [1] 0.903 0.132 0.629 0.945
    

    那么,它有什么缺陷呢 Map 上面的引语是指什么?

    0 回复  |  直到 5 年前
        1
  •  1
  •   Waldi    5 年前

    Map 是包装纸 mapply :

    Map <- function (f, ...) 
    {
      f <- match.fun(f)
      mapply(FUN = f, ..., SIMPLIFY = FALSE)
    }
    

    记录 mapply 告诉我们:

    mapply 电话 FUN 为了。。。(重新循环到最长的长度,除非任何长度为零),后跟MoreArgs中给出的参数。如果。。。或者叫更多的人。

    这意味着,即使你提供了一个不应该改变的参数,它也会作为一个向量循环使用,而不是像标准函数参数那样保持原样。

    如果非变参数本身是一个向量,这会产生很大的不同:

    f <- function(x,coef) {paste(coef[1],'*', x ,'+',coef[2])}
    
    Map(f,1:3,c(2,3))
    [[1]]
    [1] "2 * 1 + NA"
    
    [[2]]
    [1] "3 * 2 + NA"
    
    [[3]]
    [1] "2 * 3 + NA"
    
    Warning message:
    In mapply(FUN = f, ..., SIMPLIFY = FALSE) :
      longer argument is not a multiple of length of shorter
    

    相反地 purrr::map 允许不发生变化的论点,这两个例子之间的差异说明了上述引用的作者可能的意思:

    purrr::map(1:3,f,c(2,3))
    
    [[1]]
    [1] "2 * 1 + 3"
    
    [[2]]
    [1] "2 * 2 + 3"
    
    [[3]]
    [1] "2 * 3 + 3"