Reputation:
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
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
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
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