 
 (defn melt
   "Melt an object into a form suitable for easy casting, like a melt function in R.
-  It accepts multiple pivot keys (identifier variables that are reproduced for each
-  row in the output).
+  It accepts multiple pivot keys (identifier variables that are
+  reproduced for each row in the output).
+
   (use '(incanter core charts datasets))
   (view (with-data (melt (get-dataset :flow-meter) :Subject)
   (line-chart :Subject :value :group-by :variable :legend true)))
-  See http://www.statmethods.net/management/reshape.html for more examples."
+
+  See http://www.statmethods.net/management/reshape.html for more
+  examples."
   [dataset pivot-keys]
   (letfn [(col-partition [cols] (map (fn [c] [c]) cols))
           (build-row [[c] row] {:variable c :value (c row)})]
     (melt-gen dataset pivot-keys [:variable :value] col-partition build-row)))
 
 (defn ^:no-doc melt-column-groups
-  "Melts a dataset into groups defined by the list of given column names. Given a collection of pivot columns and a collection
-  of group column names, this splits each row in the input into a collection of groups and creates a row in the output for each
-  group. The groups are all the length of the column name group and it is an error if the size of the group does not divide the number
-  of non-fixed columns exactly.
+  "Melts a dataset into groups defined by the list of given column
+  names. Given a collection of pivot columns and a collection of group
+  column names, this splits each row in the input into a collection of
+  groups and creates a row in the output for each group. The groups
+  are all the length of the column name group and it is an error if
+  the size of the group does not divide the number of non-fixed
+  columns exactly.
 
   For example, given an input table:
+
   ----------------------------------------------------------------------------------------------------
   | :measure | :q1-2013 | :q2-2013 | :q3-2013 | :q4-2013 | :q1-2014 | :q2-2014 | :q3-2014 | :q4-2014 |
   |--------------------------------------------------------------------------------------------------|
   | :sales   | 100      | 250      | 200      | 400      | 90       | 200      | 150      | 600      |
   ----------------------------------------------------------------------------------------------------
 
-  This can be seen as a table with a fixed :measure column and two groups containing four financial quarters. This table can be converted with
+  This can be seen as a table with a fixed :measure column and two
+  groups containing four financial quarters. This table can be
+  converted with
+
   (melt-column-groups [:sales] [:q1 :q2 :q3 :q4])
 
   into the table:

  | :sales   | 100    | 250   | 200   | 400   |
  | :sales   | 90     | 200   | 150   | 600   |
  ---------------------------------------------
  
  dataset: The input dataset to melt.
  pivot-keys: The fixed group of columns to copy to each output row.
  output-column-names: Collection of column names that defines the gropus from the input row."
  [dataset pivot-keys output-column-names]
  (let [output-column-names (lift->vector output-column-names)]
    (letfn [(col-partition [cols]

   [grafter.tabular.common :refer :all]))

(defn mapcat-rows
  "Transforms a dataset by performing a mapcat operation on the
  rows. Each row in the input is transformed to multiple rows in the
  output by the given transform function.  dataset: The dataset to
  transform.  columns: The collection of columns in the output
  dataset.  f: function (Row -> Seqable Row) which transforms each row
  in the input into a sequence of new rows in the output. Each output
  row should contain the columns passed in the columns parameter."
  [dataset columns f]
  (-> (make-dataset (mapcat f (:rows dataset)) columns)
      (with-meta (meta dataset))))

(defn- melt-gen
  "Generalised version of melt.

  Takes the following arguments:

  - dataset: The dataset to melt.

  - pivot-keys: The collection of fixed columns in the output table.

  - generated-column-names: The collection of new columns in the
  output table. The output table will have (concat pivot-keys
  generated-column-names) columns.

  - col-partition-fn: Function to group the non-fixed columns into a
  number of partitions. A new row will be created for every partition
  in every row in the input table. For example, if the input table has
  4 rows, and col-partition-fn creates 3 groups for the non-fixed
  columns in the input, then the output table will contain 3 * 4 = 12
  rows.

  - row-builder-fn: Function (ColumnPartition -> Row -> RowFragment).
  This function is used to create the variable fragment of an output
  row given the source row in the input table and the correspdoning
  column partition returned from col-partition-fn. The row in the
  output table is created by merging the variable fragment returned
  from this function with the fixed part defined by the
  pivot-keys. The returned fragment should contain values for the
  column names in the generated-column-names parameter."

  [dataset pivot-keys generated-column-names col-partition-fn row-builder-fn]
  (let [canonicalise-key (partial resolve-column-id dataset)
        pivot-keys (map canonicalise-key (lift->vector pivot-keys))
