【问题标题】:function for dplyr with argument that defaults to "."dplyr 的函数,参数默认为“。”
【发布时间】:2018-03-22 12:35:41
【问题描述】:

假设我想对 tibble 中的所有列求和,以创建一个名为“total”的新列。我可以这样做:

library(tibble)
library(dplyr)

set.seed(42)
N <- 10
Df <- tibble(p_1 = rnorm(N),
             p_2 = rnorm(N),
             q_1 = rnorm(N),
             q_2 = rnorm(N))

# Works fine
Df %>% mutate(total = apply(., 1, sum))

我可以像这样创建一个辅助函数,

myfun <- function(Df){
  apply(Df, 1, sum)
}

# Works fine
Df %>% mutate(total = myfun(.))

但是假设这个myfun 通常会以这种方式使用,即在dplyr 动词函数中,然后是“。”引用数据框是多余的,如果myfun 函数可以将其替换为默认值,那就太好了。我想要这样的东西:

myfun2 <- function(Df=.){
   apply(Df, 1, sum)
}

这不起作用。

Df %>% mutate(total = myfun2())
Error in mutate_impl(.data, dots) : 
 Evaluation error: object '.' not found.

因为我什至不确定“。”工作,我不认为我可以更好地提出问题,但基本上,我想知道是否有一种说法,实际上,如果Df 未在myfun2 中定义,则获取数据框通常由“.”引用?

【问题讨论】:

    标签: r dplyr nse


    【解决方案1】:

    一种选择是 quote 函数,然后使用 !! 进行评估

    library(tidyverse)
    myfun <- function() {
       quote(reduce(., `+`))
    }
    
    r1 <- Df %>% 
              mutate(total = !! myfun())
    r1
    # A tibble: 10 x 5
    #       p_1    p_2    q_1     q_2  total
    #     <dbl>  <dbl>  <dbl>   <dbl>  <dbl>
    # 1  1.37    1.30  -0.307  0.455   2.82 
    # 2 -0.565   2.29  -1.78   0.705   0.645
    # 3  0.363  -1.39  -0.172  1.04   -0.163
    # 4  0.633  -0.279  1.21  -0.609   0.960
    # 5  0.404  -0.133  1.90   0.505   2.67 
    # 6 -0.106   0.636 -0.430 -1.72   -1.62 
    # 7  1.51   -0.284 -0.257 -0.784   0.186
    # 8 -0.0947 -2.66  -1.76  -0.851  -5.37 
    # 9  2.02   -2.44   0.460 -2.41   -2.38 
    #10 -0.0627  1.32  -0.640  0.0361  0.654
    

    请注意,reduce 用于更符合tidyverse,但也可以引用 OP 的函数并获得相同的结果

    myfun2 <- function() {
       quote(apply(., 1,  sum ))
    }
    
    r2 <- Df %>%
            mutate(total = !! myfun2())
    all.equal(r2$total, r1$total)
    #[1] TRUE
    

    【讨论】:

    • 使用reduce 的另一个原因是它比applyrowSums 更快
    猜你喜欢
    • 2016-07-17
    • 1970-01-01
    • 1970-01-01
    • 2019-09-11
    • 2021-08-27
    • 2017-08-03
    • 2012-02-03
    • 1970-01-01
    相关资源
    最近更新 更多