В F # есть ли такие операции, как «расплавление» или «приведение» в R? - PullRequest
5 голосов
/ 01 марта 2012

Melt и Cast являются популярными операциями для обработки данных в R. В F # это будут последовательности записей одного типа или что-то похожее на них.

Вам известны какие-либо такие функции в F #?

(Если нет, то кому было бы интересно сделать какую-то их строго типизированную версию ...)

Дополнительная информация:

Melt принимает таблицу каквход.Он имеет заголовок столбца (наши поля записи) и ряд строк.Эти столбцы могут быть сгруппированы в набор «идентификаторов» и набор «переменных»

Melt переводит эту таблицу в новую каноническую форму со следующими столбцами: идентификаторы, столбец с именем «переменная», столбец с именем @ "value"

Если у вас изначально было 10 «переменных», таких как размер, вес и т. д., то для каждой предыдущей записи у вас будет 10 записей в канонической форме со значениями встолбец @ 'variable' заполняется заголовком предыдущих столбцов из ваших 'переменных'

Приведите, наоборот, восстановить таблицу из расплавленной.

Короткий пример на R:melt берет данные (dat), которые выглядят следующим образом:

  a          b         c
1 1 0.48411551 0.2372291
2 2 0.58850308 0.3968759
3 3 0.74412592 0.9718320
4 4 0.93060118 0.8665092
5 5 0.01556804 0.2512399

и делает их похожими на это:

> melt(dat,id.vars = "a")
   a variable      value
1  1        b 0.48411551
2  2        b 0.58850308
3  3        b 0.74412592
4  4        b 0.93060118
5  5        b 0.01556804
6  1        c 0.23722911
7  2        c 0.39687586
8  3        c 0.97183200
9  4        c 0.86650918
10 5        c 0.25123992

cast по сути делает обратное.

Эти 2 операции чрезвычайно мощные на повседневной основе.Если они у вас есть, это меняет ваше мышление, очень похоже на то, как это делает FP.

Ответы [ 2 ]

2 голосов
/ 01 марта 2012

Предполагая, что melt аналогичен unpivot в SQL Server, это должно помочь:

let melt keys (table: DataTable) = 
  let out = new DataTable()
  let keyCols, otherCols = 
    table.Columns
    |> Seq.cast<DataColumn>
    |> Seq.toArray
    |> Array.partition (fun c -> keys |> Seq.exists (fun k -> k = c.ColumnName))
  for c in keyCols do
    out.Columns.Add(c.ColumnName) |> ignore
  out.Columns.Add("Key", typeof<string>) |> ignore
  out.Columns.Add("Value") |> ignore
  for r in table.Rows do
    for c in otherCols do
      let values = [|
        for c in keyCols do yield r.[c]
        yield box c.ColumnName
        yield r.[c]
      |]
      out.Rows.Add(values) |> ignore
  out

Вот небольшой тест для проверки:

let table = new DataTable()
[|"Country", typeof<string>
  "2001", typeof<int>
  "2002", typeof<int>
  "2003", typeof<int>|]
|> Array.map (fun (name, typ) -> new DataColumn(name, typ))
|> table.Columns.AddRange

[
  "Nigeria", 1, 2, 3
  "UK", 2, 3, 4
]
|> List.iter (fun (a, b, c, d) -> table.Rows.Add(a, b, c, d) |> ignore)

let table2 = table |> melt ["Country"]

table2.Rows
|> Seq.cast<DataRow>
|> Seq.iter (fun r ->
  for (c: DataColumn) in table2.Columns do
    printfn "%A: %A" c.ColumnName r.[c]
  printfn "")

что дает

"Country": "Nigeria"
"Key": "2001"
"Value": "1"

"Country": "Nigeria"
"Key": "2002"
"Value": "2"

...

Предполагая, что cast идет другим путем (то есть pivot), вы сможете взять этот код и придумать перевод.

Если вы 'Если вы делаете это много, вам может быть проще загрузить ваши данные в SQL Server и использовать встроенные операторы.

0 голосов
/ 16 апреля 2012

Вам известны какие-либо такие функции в F #?

В стандартной библиотеке F # таких функций нет.

Краткий пример в R

Данные вашего примера могут быть записаны на F # следующим образом:

let header, data =
  [ "a"; "b"; "c" ],
  [ 1, 0.48411551, 0.2372291
    2, 0.58850308, 0.3968759
    3, 0.74412592, 0.9718320
    4, 0.93060118, 0.8665092
    5, 0.01556804, 0.2512399 ]

, а затем «расплавлены» следующим образом:

let melt header data =
  let header, data = Array.ofSeq header, Array.ofSeq data
  [ header.[0], "variable", "value" ],
  [ for a, b, c in data do
      yield a, "b", b
      yield a, "c", c ]

Обратите внимание: статическая типизациятребует, чтобы ваши столбцы "b" и "c" содержали значения одного и того же типа, потому что они были объединены в один столбец.

Эти 2 операции чрезвычайно эффективны в повседневной работе.Если они у вас есть, это меняет ваше мышление, очень похоже на то, как это делает FP.

Я не понимаю, почему.Я подозреваю, что это проблема XY, и вы описываете, как проблемы могут быть решены в R, когда ту же проблему лучше решить, используя более типичный подход в F #, такой как отображение «а» в карту из «переменной» в «значение ", но не имея представления о том, что кому-то могут понадобиться эти функции, я не могу быть уверен.

...