SEXP check_grouped(RObject data) { static SEXP groups_symbol = Rf_install("groups"); static SEXP vars_symbol = Rf_install("vars"); // compat with old style grouped data frames SEXP vars = Rf_getAttrib(data, vars_symbol); if (!Rf_isNull(vars)) { DataFrame groups = build_index_cpp(data, SymbolVector(vars)); data.attr("groups") = groups; } // get the groups attribute and check for consistency SEXP groups = Rf_getAttrib(data, groups_symbol); // groups must be a data frame if (!is<DataFrame>(groups)) { bad_arg(".data", "is a corrupt grouped_df, the `\"groups\"` attribute must be a data frame"); } // it must have at least 1 column int nc = Rf_length(groups); if (nc <= 1) { bad_arg(".data", "is a corrupt grouped_df, the `\"groups\"` attribute must have at least two columns"); } // the last column must be a list and called `.rows` SEXP names = Rf_getAttrib(groups, R_NamesSymbol); SEXP last = VECTOR_ELT(groups, nc - 1); static String rows = ".rows"; if (TYPEOF(last) != VECSXP || STRING_ELT(names, nc - 1) != rows) { bad_arg(".data", "is a corrupt grouped_df, the `\"groups\"` attribute must have a list column named `.rows` as last column"); } return data ; }
SymbolVector GroupedDataFrame::group_vars(SEXP x) { check_grouped(x); static SEXP groups_symbol = Rf_install("groups"); SEXP groups = Rf_getAttrib(x, groups_symbol); int n = Rf_length(groups) - 1; CharacterVector vars = Rf_getAttrib(groups, R_NamesSymbol); vars.erase(n); return SymbolVector(vars); }
SymbolVector get_vars(SEXP x) { static SEXP vars_symbol = Rf_install("vars"); return SymbolVector(Rf_getAttrib(x, vars_symbol)); }