代码之家  ›  专栏  ›  技术社区  ›  Kay

在编程中使用dplyr filter()

  •  6
  • Kay  · 技术社区  · 7 年前

    我正在编写函数,希望使用dplyr的filter()函数来选择满足条件的数据帧行。这是我的代码:

    library(tidyverse)
    
    df <-data.frame(x = sample(1:100, 50), y = rnorm(50), z = sample(1:100,50), w = sample(1:100, 50),
                p = sample(1:100,50))
    
    new <- function(ang,brad,drau){
      df%>%filter(!!drau %in% 1:50)%>%select(ang,brad) -> A
    return(A)
    }
    
    brand <- c("z","w","p")
    lapply(1:3, function(i) new(ang = "x", brad = "y", drau = brand[i]))%>%bind_rows()
    

    每当我运行这个函数时,它看起来就像 filter

    我该怎么做?

    使现代化

    new <- function(ang,brad,drau){
      df%>%filter(!!drau > 50)%>%select(ang,brad) -> A
    return(A)
    }
    
    lapply(1:3, function(i) new(ang = "x", brad = "y", drau = brand[i]))%>%bind_rows()
    

    然而,每个循环的结果都是相同的。为什么会这样?还有为什么我不能使用 %in% .

    4 回复  |  直到 7 年前
        1
  •  9
  •   dmi3kno    7 年前

    我同意@hrbrmstr的标准评估解决方案。正如@hadley所建议的那样 today 以下是NSE解决方案:

    library(tidyverse)
    
    df <-data.frame(x = sample(1:100, 50), 
                    y = rnorm(50), 
                    z = sample(1:100,50), 
                    w = sample(1:100, 50),
                    p = sample(1:100,50))
    
    new <- function(ang, brad, drau){
      ang  <- enquo(ang)
      brad <- enquo(brad)
      drau <- enquo(drau)
    
      df %>% filter(UQ(drau) %in% 1:50) %>%
        select(UQ(ang),UQ(brad)) 
    }
    
    brand <- c("z","w","p")
    brand <- rlang::syms(brand)
    
    map_df(brand, ~new(ang = x, brad = y, drau = UQ(.x)))
    
        2
  •  8
  •   hrbrmstr    7 年前

    这似乎是你想要的(但需要你确认):

    library(tidyverse)
    library(rlang)
    
    set.seed(1492)
    
    xdf <- data_frame(
      x = sample(1:100, 50),
      y = rnorm(50), 
      z = sample(1:100,50), 
      w = sample(1:100, 50),
      p = sample(1:100,50)
    )
    
    new_df <- function(ang, brad, drau) {
      drau <- sym(drau)
      filter(xdf, UQE(drau) %in% 1:50) %>% 
        select(ang, brad)
    }
    
    brand <- c("z", "w", "p")
    
    map_df(brand, ~new_df(ang = "x", brad = "y", drau = .x))
    

    df ,它是 stats pkg和我尽量避免再使用它。

    既然你在使用tidyverse,不妨利用 map_df() 从…起 purrr

        3
  •  1
  •   Kay    4 年前

    具有 UQE !!sym()

    library(rlang)
    library(tidyverse)
    
    df <-data.frame(x = sample(1:100, 50), y = rnorm(50), z = sample(1:100,50), w = sample(1:100, 50),
                    p = sample(1:100,50))
    
    new <- function(ang,brad,drau){
      df%>%filter(!!sym(drau) %in% 1:50)%>%select(!!sym(ang), !!sym(brad)) -> A
      return(A)
    }
    
    brand <- c("z","w","p")
    lapply(1:3, function(i) new(ang = "x", brad = "y", drau = brand[i]))%>%bind_rows()
    

    !!enquo()

    new <- function(ang,brad,drau){
      df%>%filter(!!enquo(drau) %in% 1:50)%>%select(!!enquo(ang), !!enquo(brad)) -> A
      return(A)
    }
    
    > head(new(ang = x, brad = y, drau = z))
        x           y
    1  44  0.47702540
    2  84 -1.09670409
    3  59 -0.20556334
    4  81 -0.46306635
    5  93  1.36845485
    6   8  0.37392587
    
        4
  •  0
  •   Dexterity    3 年前

    我有一个类似的问题,对我有效的简单修复方法是在“filter”动词中使用“.data”代词,特别是在这种情况下:

    filter(.data[[drau]] %in% 1:50)
    

    更多信息请点击此处: https://tinyheero.github.io/2020/03/01/use-data-env-pronouns-tidyverse.html 莱昂内尔·亨利最近在Rstudio的youtube频道上的谈话也很有帮助。

    library(tidyverse)
    
    df <-data.frame(x = sample(1:100, 50), y = rnorm(50), z = sample(1:100,50), w = sample(1:100, 50),
                    p = sample(1:100,50))
    
    new <- function(ang,brad,drau){
      df%>%filter(.data[[drau]] %in% 1:50)%>%select(ang,brad) -> A
      return(A)
    }
    
    brand <- c("z","w","p")
    lapply(1:3, function(i) new(ang = "x", brad = "y", drau = brand[i]))%>%bind_rows()