【问题标题】:Creating a loop for filter() and group_by() from dplyr从 dplyr 为 filter() 和 group_by() 创建一个循环
【发布时间】:2021-12-13 07:04:15
【问题描述】:

在下面我的玩具data 中,我重复group_by()filter() 变量:samplegroupoutcome(但不是time)。

我想知道是否有一种功能解决方案,我们可以在如下所示的foo() 函数内以循环方式提供我们想要group_by()filter() 的任意数量变量的名称?

library(tidyverse)

data <- expand_grid(study=1:3,sample=1:2,group=1:3,outcome=c("A","B"),time=0:2)

get_rows <- function(x) {  # Helper function used in `filter()`
  u <- unique(x) 
  n <- sample(c(if(is.character(x)) 0 else min(u)-1, u), 1)
  if(n == n[1]) TRUE else x == n
}


DF <- data %>%
  group_by(study) %>%
  filter(get_rows(sample)) %>% # for sample
  ungroup()

DF2 <- DF %>%
  group_by(study) %>%
  filter(get_rows(group)) %>% # for group
  ungroup()

DF3 <- DF2 %>%
  group_by(study) %>%
  filter(get_rows(outcome)) %>% # for outcome
  ungroup()
#============================================ HOW TO LOOP ABOVE IN `foo()` BELOW?
foo <- function(data, ..., exclude_vars = c("time")){
  
  ## SOLUTION
}

【问题讨论】:

    标签: r dataframe function loops tidyverse


    【解决方案1】:

    如果您使用 dplyr .data 代词,您可以遍历字符串中的变量名称。例如

    foo <- function(data, exclude_vars = c("time", "study")){
      vars <- setdiff(names(data), exclude_vars)
      for (var in vars) {
        data <- data %>% 
          group_by(study) %>% 
          filter(get_rows(.data[[var]])) %>%
          ungroup()
      }
      data
    }
    foo(data)
    

    如果您愿意,可以使用 purrr::reduce 而不是循环

    foo <- function(data, exclude_vars = c("time", "study")){
      vars <- setdiff(names(data), exclude_vars)
      cleanFn <- function(data, var) data %>% 
        group_by(study) %>% 
        filter(get_rows(.data[[var]])) %>% 
        ungroup()
      reduce(vars, cleanFn, .init=data)
    }
    foo(data)
    

    【讨论】:

    • 我没有注意到study 是不变的。我已更新以确保它始终按study 分组。在问题中使用所需的输出来验证所提出的解决方案是否确实正常工作会很有帮助。
    • 函数需要是reduce的第二个参数。请参阅?reduce 帮助页面。试试purrr::reduce(vars, cleanFn, g_by, .init=data)
    • 嗨@MrFlick,你知道this function question的答案吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多