在新的dplyr函数中加入split

时间:2017-11-18 22:29:30

标签: r dplyr

我正在尝试使用dplyr在R中编写一个函数,这将允许我获取数据集,将其拆分为一个因子,然后在这些子集上运行一系列其他更复杂的用户定义函数。 / p>

我的问题是我不确定如何在函数调用中指定参数,以便split()识别并正确解释输入。

以下玩具数据和简化功能。我希望能够在grp1上运行一次这个函数,在grp2上运行一次。

非常感谢您的任何想法/帮助!

library(tidyverse)

# Create toy data
res <- tibble(
  x = runif(n = 25, 1, 100),
  g1 = sample(x = 1:3, size = 25, replace = T),
  g2 = sample(x = 1:3, size = 25, replace = T)
)

# Apply function after splitting by grouping variable 1
res %>%
  split(.$g1) %>%
  map_df(~ mean(.$x))

# Write function to allow different grouping variables (tried to follow the programming advice re dplyr functions even though I know split is a base function)
new_func1 <- function(data_in, grp) {

  grp <- enquo(grp)

  data_in %>%
    split(!!grp) %>%
    map_df(~ mean(x))
}

# All result in errors
new_func1(data_in = res, grp = g1)
new_func1(data_in = res, grp = ".$g1")
new_func1(data_in = res, grp = quote(.$g1))

# Try using quote
new_func2 <- function(data_in, grp) {

  data_in %>%
    split(grp) %>%
    map_df(~ mean(x))
}

# All result in errors
new_func2(data_in = res, grp = g1)
new_func2(data_in = res, grp = ".$g1")
new_func2(data_in = res, grp = quote(.$g1))

1 个答案:

答案 0 :(得分:2)

首先,您无法在.中省略map_df()map_df(~ mean(.$x))是正确的。{/ p>

其次,split()是基本功能,您无法使用!!!!仅在函数理解此表示法时才有效。所以,你可以

  1. pull()之类的函数中取消引用它。
  2. 将其转换为文字。
  3. 例如:

    new_func3 <- function(data_in, grp) {
      grp <- rlang::enquo(grp)
    
      data_in %>%
        split(pull(., !!grp)) %>%
        map_df(~ mean(.$x))
    }
    
    new_func4 <- function(data_in, grp) {
      grp <- rlang::enquo(grp)
      grp_chr <- rlang::quo_text(grp)
    
      data_in %>%
        split(.[[grp_chr]]) %>%
        map_df(~ mean(.$x))
    }
    

    或者,如果您只想将grp作为字符传递,这就足够了:

    new_func5 <- function(data_in, grp_chr) {
      data_in %>%
        split(.[[grp_chr]]) %>%
        map_df(~ mean(.$x))
    }