简体   繁体   English

reshape2::melt 的 tidyverse 模拟可以做所有事情吗?

[英]tidyverse analog of reshape2::melt that does everything?

The answers to this question document that the tidyverse analog of reshape2::melt() is tidyr::pivot_longer() . 这个问题的答案记录了reshape2::melt()的 tidyverse 模拟是tidyr::pivot_longer() That's true, as far as it goes, but I still find the process of melting a matrix with defined dimnames in tidyverse much less convenient than the tidyverse equivalent.就目前而言,这是真的,但我仍然发现在 tidyverse 中熔化具有定义的 dimnames 的矩阵的过程比 tidyverse 等价物更不方便。

Example:例子:

z <- matrix(1:12, ncol=3, 
       dimnames = list(a = 1:4, b = LETTERS[1:3]))

reshape2::melt(z) automatically gives me a data frame with the ID columns named "a" and "b", corresponding to the elements of names(dimnames(z)) . reshape2::melt(z)自动给我一个数据框,其中 ID 列名为“a”和“b”,对应于names(dimnames(z))的元素。

I originally had a somewhat clunky solution here but realized it didn't work.我最初在这里有一个有点笨拙的解决方案,但意识到它没有用。 I think the required steps are认为所需的步骤是

  • store the row-dimension name and column-dimension names存储行维度名称和列维度名称
  • convert to a data frame转换为数据框
  • add the rowname as a column with name "tmp" (with tibble::rownames_to_column("tmp") )将行名添加为名称为“tmp”的列(使用tibble::rownames_to_column("tmp")
  • pivot_longer() with -tmp and set names_to to the column-dimension name pivot_longer()-tmp并将names_to设置为列维度名称
  • rename "tmp" to the row_dimension name (could save a step if we did NSE magic)将“tmp”重命名为 row_dimension 名称(如果我们使用 NSE 魔法可以节省一步)

This seems much clunkier than melt() .这似乎比melt()笨拙得多。 Obviously I could write a utility function to encapsulate this, but I'm wondering if I'm missing a solution that is more compact and/or tidyverse-idiomatic.显然我可以编写一个实用程序 function 来封装它,但我想知道我是否缺少一个更紧凑和/或 tidyverse-idiomatic 的解决方案。 What do other people do when the first step in their data pipeline is a matrix?当数据管道的第一步是矩阵时,其他人会怎么做?

If you don't mind having a base R function in your pipeline, then you could do:如果你不介意在你的管道中有一个 base R function,那么你可以这样做:

z %>%
  as.table() %>%
  as_tibble()
#> # A tibble: 12 x 3
#>    a     b         n
#>    <chr> <chr> <int>
#>  1 1     A         1
#>  2 2     A         2
#>  3 3     A         3
#>  4 4     A         4
#>  5 1     B         5
#>  6 2     B         6
#>  7 3     B         7
#>  8 4     B         8
#>  9 1     C         9
#> 10 2     C        10
#> 11 3     C        11
#> 12 4     C        12

Of course, this is just a slightly contrived tidyverse version of the base R equivalent, which is difficult to beat for brevity.当然,这只是基本 R 等价物的稍微做作的 tidyverse 版本,为简洁起见很难击败。

as.data.frame(as.table(z))
#>    a b Freq
#> 1  1 A    1
#> 2  2 A    2
#> 3  3 A    3
#> 4  4 A    4
#> 5  1 B    5
#> 6  2 B    6
#> 7  3 B    7
#> 8  4 B    8
#> 9  1 C    9
#> 10 2 C   10
#> 11 3 C   11
#> 12 4 C   12

And these both give the same result as reshape2::melt :这些都给出与reshape2::melt相同的结果:

reshape2::melt(z)
#>    a b value
#> 1  1 A     1
#> 2  2 A     2
#> 3  3 A     3
#> 4  4 A     4
#> 5  1 B     5
#> 6  2 B     6
#> 7  3 B     7
#> 8  4 B     8
#> 9  1 C     9
#> 10 2 C    10
#> 11 3 C    11
#> 12 4 C    12

Created on 2023-01-24 with reprex v2.0.2创建于 2023-01-24,使用reprex v2.0.2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM