user3904098
user3904098

Reputation:

Dplyr, filter and SE

I have a data frame with 3 columns A, B, C and I'd like to build a function to only keep rows where column A is lower to another column (could be column B or C)

I know we need to use filter_ and SE to make this possible with dplyr and I had a look at the vignette but I don't understand how it works.'

How could I transform this function into a SE function?

df = data.frame(columnA = 1:100,
                columnB = rnorm(100, 50, 10),
                columnC = rnorm(100, 50, 10))

fct = function(df,column_name){
  df2 = df %>% filter(columnA < column)
return(df2)
}

Upvotes: 3

Views: 393

Answers (3)

CoderGuy123
CoderGuy123

Reputation: 6669

Here's a function that works with character input/SE.

fct = function(df, column_name){
  #convert to sym from chr
  column_name = sym(column_name)

  #filter
  df %>% filter(columnA < column_name)
}

Test:

> df %>% fct("columnB") %>% head()
  columnA  columnB  columnC
1       1 68.80929 56.49032
2       2 58.17927 68.06920
3       3 57.52833 66.00263
4       4 41.38442 57.58875
5       5 38.93989 61.93183
6       6 51.10835 54.70835

I am not sure why one has to do the sym() call first.

Upvotes: 0

Paul
Paul

Reputation: 3361

NGaffney's answer is the SE version. Here's the NSE version, meaning it allows you to enter an unquoted column name:

require(dplyr)
df = data.frame(columnA=20, columnB=50, columnC=15)

fct = function(df,column_NSE){
  column_name = deparse(substitute(column_NSE))
  df2 = df %>% filter_(paste("columnA < ", column_name))
  return(df2)
}

Test run:

> fct(df,columnB)
  columnA columnB columnC
1      20      50      15

> fct(df,columnC)
[1] columnA columnB columnC
<0 rows> (or 0-length row.names)

Upvotes: 0

NGaffney
NGaffney

Reputation: 1532

Transforming your expression inside filter_ into a string is one way to do it:

fct = function(df, column_name){
  df2 = df %>% filter_(paste("columnA <", column_name))
  return(df2)
}
nrow(fct(df, "columnB"))
## [1] 50

Upvotes: 1

Related Questions