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

问题描述 投票:1回答:2

我想在函数中使用一个函数,其列名在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
)

r function debugging dplyr
2个回答
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
)

- 输出

#$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

对于'fn2',使用enquo将'.y','。gen','。env'转换为quosure,然后使用!!计算'fn1'的参数

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
)

- 输出

#$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
投票

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

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
© www.soinside.com 2019 - 2024. All rights reserved.