Melt和Cast是在R中处理数据的常用操作。
在F#中,它将是相同类型或与其相似的记录的序列。

您知道F#中有任何此类功能吗?

(如果没有,谁会对制作它们的强类型版本感兴趣?)

更多信息:

融化将表格作为输入。
它具有列标题(我们的记录字段)和一系列行。
这些列可以分为一组“标识符”和一组“变量”

Melt将此表格以新的规范形式放入表格,其中各列现在为:
标识符,名为@“variable”的列,名为@“value”的列

如果您最初有10个“变量”(例如大小,重量等),那么对于每个先前的记录,将有10条规范形式的记录,其中@'variable'列中的值将填充先前的标题您的“变量”中的列

相反,类型转换则是从融化的 table 中重建一张 table 。

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一样改变您的想法。

最佳答案

假设melt与SQL Server的unpivot相似,则应该做到这一点:

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并使用内置运算符会更容易。

关于r - 在F#中,R中是否有类似 'melt'或 'cast'的操作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9522521/

10-12 17:48