This is an extra entity that Bruno created to make it possible two split multiple species, elements, and modification types into different rows

The important thing here is the abundance_key, a unique id for everything we need to count (so for the rows with 6 species, each of them will be counted once)

new columns

This one creates a bunch of new columns, some of which are just a single step towards a later goal that will be used in other entities.

Input columnscreated columns
materialelement_name, modification_type
speciesspecies_1, species_2, species_3, species_4, species_5, species_6
unique_row_identiferabundance_key

abundance_key

uses {unique_row_identifier}-{element_name}-{species_split}-{modification_type}to add the info from the other new columns to the unique_row_identifer to enable us to still have a unique row identifier after pulling each species in the same cell into their own rows (and duplicating all of the information associated with those rows)

species_1 to species_6

uses =trim(regex_extract(lower(species), '^([^,]+)', 1)) to pull the first species from a list of them in a single cell
(repeats with slightly different code to extract the next species in the list, up to species_6, because there are that many in one of them!)

element_name

uses =regex_extract(trim(replace(replace(replace(replace(replace(replace(replace(replace(lower(trim(material)),'(ej förkolnat)',''),'förkolnat',''),'obrända',''),'obränt',''),'brända',''),' ', ' '),' ,', ','),',,', ',')),'^[,;\s]*(.*?)[,;\s]*$', 1) to delete from the material column the words that describe “modifications” to the material (the item was burned, not burned, etc.), leaving behind only the word describing the material itself (träkol, ben, etc.)

modification_type

uses =regex_extract(replace(replace(concat(coalesce(regex_extract(lower(trim(material)), '\(ej förkolnat\)'), ''), ',',coalesce(regex_extract(lower(trim(material)), '(?<!ej )förkolnat'), ''),',',coalesce(regex_extract(lower(trim(material)), 'obrända'), ''),',', coalesce(regex_extract(lower(trim(material)), 'obränt'),''),',',coalesce(regex_extract(lower(trim(material)), '(?<!o)brända'), '')),',,', ','),',,', ','),'^,*(.*?),*$',1) to extract from the material column the words that describe “modifications” to the material (the item was burned, not burned, etc.)

abundance_key

uses {unique_row_identifier}-{element_name}-{species_split}-{modification_type} to interpolate a unique key for each thing that will be counted in tbl_abundances

Unnest tab

This one uses some of the above columns to create new rows for each unique species from a single row, without losing any of its associated data

boxes to fill incolumns assigned
ID Variables
(Columns to keep as-is)
species
unique_row_identifer
element_name
material
modification_type
Value Variables
(Columns to unpivot)
species_1 to species_6
Variable Name Column
(Name for the new column containing variable names)
species_number
Value Name Column
(Name for the new column containing values)
species_split

See also Bruno's documentation notes for Reproducing Manual Resolution Cleaning in ShapeShifter

YAML as of 2026-09-16

name: superabundance
type: entity
system_id: system_id
keys: []
columns:
  - material
  - species
  - unique_row_identifier
public_id: transition_id
source: datasheet
filters:
  - type: query
    stage: after_unnest
    query: species_split.notna() or species_number == 'species_1'
unnest:
  id_vars:
    - species
    - unique_row_identifier
    - element_name
    - material
    - modification_type
  value_vars:
    - species_1
    - species_2
    - species_3
    - species_4
    - species_6
    - species_5
  var_name: species_number
  value_name: species_split
extra_columns:
  species_1: '=trim(regex_extract(lower(species), ''^([^,]+)'', 1))'
  species_2: '=trim(regex_extract(lower(species), ''^[^,]+,\s*([^,]+)'', 1))'
  species_3: '=trim(regex_extract(lower(species), ''^[^,]+,\s*[^,]+,\s*([^,]+)'', 1))'
  species_4: '=trim(regex_extract(lower(species), ''^[^,]+,\s*[^,]+,\s*[^,]+,\s*([^,]+)'', 1))'
  species_5: '=trim(regex_extract(lower(species), ''^[^,]+,\s*[^,]+,\s*[^,]+,\s*[^,]+,\s*([^,]+)'', 1))'
  species_6: '=trim(regex_extract(lower(species), ''^[^,]+,\s*[^,]+,\s*[^,]+,\s*[^,]+,\s*[^,]+,\s*([^,]+)'', 1))'
  element_name: '=regex_extract(trim(replace(replace(replace(replace(replace(replace(replace(replace(lower(trim(material)),''(ej förkolnat)'',''''),''förkolnat'',''''),''obrända'',''''),''obränt'',''''),''brända'',''''),''  '', '' ''),'' ,'', '',''),'',,'', '','')),''^[,;\s]*(.*?)[,;\s]*$'', 1)'
  modification_type: '=regex_extract(replace(replace(concat(coalesce(regex_extract(lower(trim(material)), ''\(ej förkolnat\)''), ''''), '','',coalesce(regex_extract(lower(trim(material)), ''(?<!ej )förkolnat''), ''''),'','',coalesce(regex_extract(lower(trim(material)), ''obrända''), ''''),'','', coalesce(regex_extract(lower(trim(material)), ''obränt''),''''),'','',coalesce(regex_extract(lower(trim(material)), ''(?<!o)brända''), '''')),'',,'', '',''),'',,'', '',''),''^,*(.*?),*$'',1)'
  [[abundance_key]]: '{unique_row_identifier}-{element_name}-{species_split}-{modification_type}'