Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using dplyr filter() in programming

I am writing my function and want to use dplyr's filter() function to select rows of my data frame that satisfy a condition. This is my code:

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()

Anytime I run this function, it looks like filter doesn't select any rows that satisfy the condition.

How can I make this work?

Update

For some reason, this works when I don't use `%in%, as in;

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()

However, the results are the same for every loop. Why is this so? and also why can't I use %in%.

like image 394
Kay Avatar asked Jul 21 '17 01:07

Kay


People also ask

What does dplyr filter do?

The filter() function is used to subset a data frame, retaining all rows that satisfy your conditions. To be retained, the row must produce a value of TRUE for all conditions. Note that when a condition evaluates to NA the row will be dropped, unlike base subsetting with [ .

What does the filter () function do in R?

The filter() method in R is used to subset a data frame based on a provided condition. If a row satisfies the condition, it must produce TRUE . Otherwise, non-satisfying rows will return NA values. Hence, the row will be dropped.

How do you filter data in R programming?

The filter() method in R programming language can be applied to both grouped and ungrouped data. The expressions include comparison operators (==, >, >= ) , logical operators (&, |, !, xor()) , range operators (between(), near()) as well as NA value check against the column values.

What does %>% do in dplyr?

%>% is called the forward pipe operator in R. It provides a mechanism for chaining commands with a new forward-pipe operator, %>%. This operator will forward a value, or the result of an expression, into the next function call/expression. It is defined by the package magrittr (CRAN) and is heavily used by dplyr (CRAN).


2 Answers

I agree with @hrbrmstr's standard evaluation solution. As suggested by @hadley today here's NSE solution:

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)))
like image 194
dmi3kno Avatar answered Sep 21 '22 20:09

dmi3kno


This appears to do what you want (but it needs confirmation by you):

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))

Despite there being a plethora of "official" "tidyverse" examples using df, it's a function in the stats pkg and I try to avoid using it anymore.

Since you're using the tidyverse, might as well take advantage of map_df() from purrr.

like image 32
hrbrmstr Avatar answered Sep 20 '22 20:09

hrbrmstr