使用dplyr中编码的函数内的函数

时间:2018-02-24 12:33:44

标签: r function debugging dplyr

我想在函数中使用一个函数,其列名在dplyr中编码如下,这会引发以下错误:

  

grouped_df_impl(data,unname(vars),drop)出错:列G是   未知

代码:

# rm(list = ls())

set.seed(12345)
Y  <- rnorm(10)
Env <- paste0("E", rep(1:2, each = 5))
Gen <- paste0("G", rep(1:5, times = 2))
df1 <- data.frame(Y, Env, Gen)

fn1 <- function(.data, .gen, .env, .y){

  Y   <- deparse(substitute(.y))
  G   <- deparse(substitute(.gen))
  E   <- deparse(substitute(.env))

  ge_means <-
    .data %>%
    dplyr::group_by(!!rlang::sym(G), !!rlang::sym(E)) %>%
    dplyr::summarize(Mean = mean(!!rlang::sym(Y)))

  return(list(
    ge_means = ge_means
    ))
}

fn1(
    .data = df1
  , .gen  = Gen
  , .env  = Env
  , .y    = Y
)


fn2 <- function(.data, .gen, .env, .y){

  Y   <- deparse(substitute(.y))
  G   <- deparse(substitute(.gen))
  E   <- deparse(substitute(.env))

  ge_means1 <- 
      fn1(
          .data = .data
        , .gen  = G
        , .env  = E
        , .y    = Y
      )$ge_mean

  return(list(
    ge_means1 = ge_means1
  ))
}


fn2(
    .data = df1
  , .gen  = Gen
  , .env  = Een
  , .y    = Y
)

2 个答案:

答案 0 :(得分:1)

我们可以使用enquo代替deparse/substitute,然后使用sym转换回符号

fn1 <- function(.data, .gen, .env, .y){

  Y   <- enquo(.y)
  G   <- enquo(.gen)
  E   <- enquo(.env)

  ge_means <-
    .data %>%
    dplyr::group_by(!! G, !! E) %>%
    dplyr::summarize(Mean = mean(!! Y))

  return(list(
    ge_means = ge_means
    ))
}

fn1(
    .data = df1
  , .gen  = Gen
  , .env  = Env
  , .y    = Y
)

-output

#$ge_means
# A tibble: 10 x 3
# Groups: Gen [?]
#   Gen    Env      Mean
#   <fctr> <fctr>  <dbl>
# 1 G1     E1      0.586
# 2 G1     E2     -1.82 
# 3 G2     E1      0.709
# 4 G2     E2      0.630
# 5 G3     E1     -0.109
# 6 G3     E2     -0.276
# 7 G4     E1     -0.453
# 8 G4     E2     -0.284
# 9 G5     E1      0.606
#10 G5     E2     -0.919

对于&#39; fn2&#39;转换&#39; .y&#39;,&#39; .gen&#39;,&#39; .env&#39;与enquo进行关系,然后评估&#39; fn1&#39;使用!!

fn2 <- function(.data, .gen, .env, .y){
      Y   <- enquo(.y)
      G   <- enquo(.gen)
      E   <- enquo(.env)

     ge_means1 <-  fn1(
          .data, 
         .gen = !! G,  
         .env = !! E,   
         .y = !! Y    
      )$ge_mean

      return(list(
    ge_means1 = ge_means1
  ))

}


fn2(
    .data = df1,
   .gen  = Gen,
   .env  = Env,
   .y    = Y
)

-output

#$ge_means1
# A tibble: 10 x 3
# Groups: Gen [?]
#   Gen    Env      Mean
#   <fctr> <fctr>  <dbl>
# 1 G1     E1      0.586
# 2 G1     E2     -1.82 
# 3 G2     E1      0.709
# 4 G2     E2      0.630
# 5 G3     E1     -0.109
# 6 G3     E2     -0.276
# 7 G4     E1     -0.453
# 8 G4     E2     -0.284
# 9 G5     E1      0.606
#10 G5     E2     -0.919

答案 1 :(得分:1)

我们可以像这样使用...

fn2 <- function(...) list(ge_means1 = fn1(...)$ge_mean)

fn2(df1, Gen, Env, Y)

,并提供:

$ge_means1
# A tibble: 10 x 3
# Groups: Gen [?]
   Gen    Env      Mean
   <fctr> <fctr>  <dbl>
 1 G1     E1      0.586
 2 G1     E2     -1.82 
 3 G2     E1      0.709
 4 G2     E2      0.630
 5 G3     E1     -0.109
 6 G3     E2     -0.276
 7 G4     E1     -0.453
 8 G4     E2     -0.284
 9 G5     E1      0.606
10 G5     E2     -0.919