in src/DataFrame.cpp [337:415]
static SEXP applyFilter(SEXP df, DataFrameFilterRequest::Filter const& filter) {
SHIELD(df);
int nrow = asInt(RI->nrow(df));
if (filter.has_true_()) {
return RI->rep(true, nrow);
}
if (filter.has_composed()) {
switch (filter.composed().type()) {
case DataFrameFilterRequest_Filter_ComposedFilter_Type_AND: {
PrSEXP result = RI->rep(true, nrow);
for (auto const& f : filter.composed().filters()) {
result = RI->vectorAnd(result, applyFilter(df, f));
}
return result;
}
case DataFrameFilterRequest_Filter_ComposedFilter_Type_OR: {
PrSEXP result = RI->rep(false, nrow);
for (auto const& f : filter.composed().filters()) {
result = RI->vectorOr(result, applyFilter(df, f));
}
return result;
}
case DataFrameFilterRequest_Filter_ComposedFilter_Type_NOT: {
PrSEXP result = RI->rep(true, nrow);
for (auto const& f : filter.composed().filters()) {
result = RI->vectorAnd(result, applyFilter(df, f));
}
return RI->vectorNot(result);
}
default:
return RI->rep(true, nrow);
}
}
if (filter.has_operator_()) {
ShieldSEXP column = RI->doubleSubscript(df, filter.operator_().column() + 1);
std::string cls = getClasses(column);
std::string const& strValue = filter.operator_().value();
PrSEXP value;
if (cls == "integer") {
value = RI->asInteger(strValue);
} else if (cls == "numeric") {
value = RI->asDouble(strValue);
} else if (cls == "logical") {
value = RI->asLogical(strValue);
} else {
value = toSEXP(strValue);
}
switch (filter.operator_().type()) {
case DataFrameFilterRequest_Filter_Operator_Type_EQ:
return RI->eq(column, value);
case DataFrameFilterRequest_Filter_Operator_Type_NEQ:
return RI->neq(column, value);
case DataFrameFilterRequest_Filter_Operator_Type_LESS:
return RI->less(column, value);
case DataFrameFilterRequest_Filter_Operator_Type_GREATER:
return RI->greater(column, value);
case DataFrameFilterRequest_Filter_Operator_Type_LEQ:
return RI->leq(column, value);
case DataFrameFilterRequest_Filter_Operator_Type_GEQ:
return RI->geq(column, value);
case DataFrameFilterRequest_Filter_Operator_Type_REGEX:
try {
return RI->grepl(strValue, column);
} catch (RError const&) {
}
default:
return RI->rep(true, nrow);
}
}
if (filter.has_nafilter()) {
ShieldSEXP column = RI->doubleSubscript(df, filter.nafilter().column() + 1);
if (filter.nafilter().isna()) {
return RI->isNa(column);
} else {
return RI->vectorNot(RI->isNa(column));
}
}
return RI->rep(true, nrow);
}