`orders` is the user-supplied ordering with the remaining data-frame-supplied ordering appended if the column is used for grouping. It includes anything the user gave, for any variable, including values not present in the dataset. It's a dict where the keys are e.g. "x" or "color"
(args, grouper)
| 2436 | |
| 2437 | |
| 2438 | def get_groups_and_orders(args, grouper): |
| 2439 | """ |
| 2440 | `orders` is the user-supplied ordering with the remaining data-frame-supplied |
| 2441 | ordering appended if the column is used for grouping. It includes anything the user |
| 2442 | gave, for any variable, including values not present in the dataset. It's a dict |
| 2443 | where the keys are e.g. "x" or "color" |
| 2444 | |
| 2445 | `groups` is the dicts of groups, ordered by the order above. Its keys are |
| 2446 | tuples like [("value1", ""), ("value2", "")] where each tuple contains the name |
| 2447 | of a single dimension-group |
| 2448 | """ |
| 2449 | orders = {} if "category_orders" not in args else args["category_orders"].copy() |
| 2450 | df: nw.DataFrame = args["data_frame"] |
| 2451 | # figure out orders and what the single group name would be if there were one |
| 2452 | single_group_name = [] |
| 2453 | unique_cache = dict() |
| 2454 | |
| 2455 | for i, col in enumerate(grouper): |
| 2456 | if col == one_group: |
| 2457 | single_group_name.append("") |
| 2458 | else: |
| 2459 | if col not in unique_cache: |
| 2460 | unique_cache[col] = ( |
| 2461 | df.get_column(col).unique(maintain_order=True).to_list() |
| 2462 | ) |
| 2463 | uniques = unique_cache[col] |
| 2464 | if len(uniques) == 1: |
| 2465 | single_group_name.append(uniques[0]) |
| 2466 | if col not in orders: |
| 2467 | orders[col] = uniques |
| 2468 | else: |
| 2469 | orders[col] = list(OrderedDict.fromkeys(list(orders[col]) + uniques)) |
| 2470 | |
| 2471 | if len(single_group_name) == len(grouper): |
| 2472 | # we have a single group, so we can skip all group-by operations! |
| 2473 | groups = {tuple(single_group_name): df} |
| 2474 | else: |
| 2475 | required_grouper = [group for group in orders if group in grouper] |
| 2476 | grouped = dict(df.group_by(required_grouper, drop_null_keys=True).__iter__()) |
| 2477 | |
| 2478 | sorted_group_names = sorted( |
| 2479 | grouped.keys(), |
| 2480 | key=lambda values: [ |
| 2481 | orders[group].index(value) if value in orders[group] else -1 |
| 2482 | for group, value in zip(required_grouper, values) |
| 2483 | ], |
| 2484 | ) |
| 2485 | |
| 2486 | # calculate the full group_names by inserting "" in the tuple index for one_group groups |
| 2487 | full_sorted_group_names = [ |
| 2488 | tuple( |
| 2489 | [ |
| 2490 | ( |
| 2491 | "" |
| 2492 | if col == one_group |
| 2493 | else sub_group_names[required_grouper.index(col)] |
| 2494 | ) |
| 2495 | for col in grouper |
no test coverage detected