等同于 Scala 中 R 的 reshape2::melt()?

Equivalent of R's reshape2::melt() in Scala?

我有一个数据框,我想使用 Scala 使用多列中的值将行分解为多行。理想情况下,我希望复制 R 函数 melt().

的行为

所有列都包含 Strings

示例:我想转换这个数据框..

df.show
+--------+-----------+-------------+-----+----+
|col1    | col2       | col3       | res1|res2|
+--------+-----------+-------------+-----+----+
|       a|    baseline| equivalence| TRUE| 0.1|
|       a| experiment1| equivalence|FALSE|0.01|
|       b|    baseline| equivalence| TRUE| 0.2|
|       b| experiment1| equivalence|FALSE|0.02|
+--------+-----------+-------------+-----+----+

...进入此数据框:

+--------+-----------+-------------+-----+-------+
|col1    | col2      | col3        | key  |value|
+--------+-----------+-------------+-----+-------+
|       a|   baseline|  equivalence| res1 | TRUE |
|       a|experiment1|  equivalence| res1 | FALSE|
|       b|   baseline|  equivalence| res1 | TRUE |
|       b|experiment1|  equivalence| res1 | FALSE|
|       a|   baseline|  equivalence| res2 | 0.1  |
|       a|experiment1|  equivalence| res2 | 0.01 |
|       b|   baseline|  equivalence| res2 | 0.2  |
|       b|experiment1|  equivalence| res2 | 0.02 |
+--------+-----------+-------------+-----+-------+

注意:我从 SMV 找到了 class UnpivotOp,它完全符合我的要求:(https://github.com/TresAmigosSD/SMV/blob/master/src/main/scala/org/tresamigos/smv/UnpivotOp.scala).

不幸的是,class 是私有的,所以我不能这样做:

import org.tresamigos.smv.UnpivotOp
val melter = new UnpivotOp(df,  Seq("res1","res2"))
val melted_df = melter.unpivot()

有谁知道是否有办法通过 SMV 的一些其他 class 静态方法访问 class org.tresamigos.smv.UnpivotOp

谢谢!

感谢Andrew's Ray to 这成功了:

df.select($"col1",
          $"col2",
          $"col3",
          expr("stack(2, 'res1', res1, 'res2', res2) as (key, value)"))

或者如果 select 的表达式应该作为字符串传递(对于 df %>% sparklyr::invoke("") 很方便):

df.selectExpr("col1", 
              "col2", 
              "col3",
              "stack(2, 'res1', res1, 'res2', res2) as (key, value)")