Skip to content

Commit

Permalink
filter works with rowwise data. closes #1099
Browse files Browse the repository at this point in the history
  • Loading branch information
romainfrancois committed Aug 17, 2015
1 parent 63a816b commit 1b36d85
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 13 deletions.
4 changes: 3 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@

* `ungroup.rowwise_df` gives a `tbl_df` (#936).

* `mutate.rowwise_df` handles factors (#886).
* `mutate.rowwise_df` handles factors (#886).

* `filter` works with rowwise data (#1099).

# dplyr 0.4.2

Expand Down
29 changes: 17 additions & 12 deletions src/filter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,9 @@ inline SEXP check_filter_logical_result(SEXP tmp){
return tmp ;
}

DataFrame filter_grouped_single_env( const GroupedDataFrame& gdf, const LazyDots& dots){
typedef GroupedCallProxy<GroupedDataFrame, LazyGroupedSubsets> Proxy ;
template <typename Data, typename Subsets>
DataFrame filter_grouped_single_env( const Data& gdf, const LazyDots& dots){
typedef GroupedCallProxy<Data, Subsets> Proxy ;
Environment env = dots[0].env() ;

const DataFrame& data = gdf.data() ;
Expand All @@ -89,7 +90,7 @@ DataFrame filter_grouped_single_env( const GroupedDataFrame& gdf, const LazyDots
Proxy call_proxy( call, gdf, env ) ;

int ngroups = gdf.ngroups() ;
GroupedDataFrame::group_iterator git = gdf.group_begin() ;
typename Data::group_iterator git = gdf.group_begin() ;
for( int i=0; i<ngroups; i++, ++git){
SlicingIndex indices = *git ;
int chunk_size = indices.size() ;
Expand All @@ -107,14 +108,15 @@ DataFrame filter_grouped_single_env( const GroupedDataFrame& gdf, const LazyDots
}
}
}
DataFrame res = subset( data, test, names, classes_grouped<GroupedDataFrame>() ) ;
DataFrame res = subset( data, test, names, classes_grouped<Data>() ) ;
res.attr( "vars") = data.attr("vars") ;

return res ;
}

// version of grouped filter when contributions to ... come from several environment
DataFrame filter_grouped_multiple_env( const GroupedDataFrame& gdf, const LazyDots& dots){
template <typename Data, typename Subsets>
DataFrame filter_grouped_multiple_env( const Data& gdf, const LazyDots& dots){
const DataFrame& data = gdf.data() ;
CharacterVector names = data.names() ;
SymbolSet set ;
Expand All @@ -132,9 +134,9 @@ DataFrame filter_grouped_multiple_env( const GroupedDataFrame& gdf, const LazyDo
const Lazy& lazy = dots[k] ;

Call call( lazy.expr() ) ;
GroupedCallProxy<GroupedDataFrame> call_proxy( call, gdf, lazy.env() ) ;
GroupedCallProxy<Data, Subsets> call_proxy( call, gdf, lazy.env() ) ;
int ngroups = gdf.ngroups() ;
GroupedDataFrame::group_iterator git = gdf.group_begin() ;
typename Data::group_iterator git = gdf.group_begin() ;
for( int i=0; i<ngroups; i++, ++git){
SlicingIndex indices = *git ;
int chunk_size = indices.size() ;
Expand All @@ -156,17 +158,18 @@ DataFrame filter_grouped_multiple_env( const GroupedDataFrame& gdf, const LazyDo
}
}
}
DataFrame res = subset( data, test, names, classes_grouped<GroupedDataFrame>() ) ;
DataFrame res = subset( data, test, names, classes_grouped<Data>() ) ;
res.attr( "vars") = data.attr("vars") ;

return res ;
}

DataFrame filter_grouped( const GroupedDataFrame& gdf, const LazyDots& dots){
template <typename Data, typename Subsets>
DataFrame filter_grouped( const Data& gdf, const LazyDots& dots){
if( dots.single_env() ){
return filter_grouped_single_env(gdf, dots) ;
return filter_grouped_single_env<Data, Subsets>(gdf, dots) ;
} else {
return filter_grouped_multiple_env(gdf, dots) ;
return filter_grouped_multiple_env<Data, Subsets>(gdf, dots) ;
}
}

Expand Down Expand Up @@ -269,7 +272,9 @@ SEXP filter_impl( DataFrame df, LazyDots dots){
}
}
if( is<GroupedDataFrame>( df ) ){
return filter_grouped( GroupedDataFrame(df), dots);
return filter_grouped<GroupedDataFrame, LazyGroupedSubsets>( GroupedDataFrame(df), dots);
} else if( is<RowwiseDataFrame>(df) ){
return filter_grouped<RowwiseDataFrame, LazyRowwiseSubsets>( RowwiseDataFrame(df), dots);
} else {
return filter_not_grouped( df, dots ) ;
}
Expand Down
7 changes: 7 additions & 0 deletions tests/testthat/test-filter.r
Original file line number Diff line number Diff line change
Expand Up @@ -275,3 +275,10 @@ test_that("filter, slice and arrange preserves attributes (#1064)", {
expect_equal( res, "this is important")

})

test_that("filter works with rowwise data (#1099)", {
df <- data_frame(First = c("string1", "string2"), Second = c("Sentence with string1", "something"))
res <- df %>% rowwise() %>% filter(grepl(First, Second, fixed = TRUE))
expect_equal( nrow(res), 1L)
expect_equal( df[1,], res)
})

0 comments on commit 1b36d85

Please sign in to comment.