def nest *tree_keys, &_block
      tree_keys = tree_keys[0] if tree_keys[0].is_a? Array

      each_row.each_with_object({}) do |row, current|
        # Create tree
        *keys, last = tree_keys
        current = keys.inject(current) { |c, f| c[row[f]] ||= {} }
        name = row[last]

        if block_given?
          current[name] = yield(row, current, name)
        else
          current[name] ||= []
          current[name].push(row.to_h.delete_if { |key,_value| tree_keys.include? key })
        end
      end
    end
def nest *tree_keys, &_block
      tree_keys = tree_keys[0] if tree_keys[0].is_a? Array

      each_row.each_with_object({}) do |row, current|
        # Create tree
        *keys, last = tree_keys
        current = keys.inject(current) { |c, f| c[row[f]] ||= {} }
        name = row[last]

        if block_given?
          current[name] = yield(row, current, name)
        else
          current[name] ||= []
          current[name].push(row.to_h.delete_if { |key,_value| tree_keys.include? key })
        end
      end
    end
Return a nested hash using vector names as keys and an array constructed of
 hashes with other values. If block provided, is used to provide the
 values, with parameters +row+ of dataset, +current+ last hash on
 hierarchy and +name+ of the key to include