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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用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
)

答案

我们可以使用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
另一答案

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

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

以上是关于使用dplyr中编码的函数内的函数的主要内容,如果未能解决你的问题,请参考以下文章

R语言dplyr包使用recode函数进行数据列内容编码转换实战:类似于pandas中的map函数(例如,将内容从字符串映射到数值)

R语言dplyr处理dataframe:使用mutate函数生成新的列recode函数进行数据编码rename函数重命名字段arrange排序数据列select筛选数据filter过滤数据

将多个列变为函数会为dplyr中的结果列内的每个组件创建一个列表

R语言dplyr包的mutate函数将列添加到dataframe中或者修改现有的数据列:基于条件判断创建布尔型指示变量将异常离散编码转化为NA值

使用androidx获取片段内的actionBar

如何在 R 中使用 dplyr mutate 函数来计算运行余额?