6

我有一个二维表,在 R 中的 data.frame 中有距离(从 csv 导入):

           CP000036   CP001063      CP001368
CP000036      0           a            b
CP001063      a           0            c
CP001368      b           c            0

我想“压平”它。我在第一列中有一个轴的值​​,在第二列中有另一个轴的值​​,然后在第三列中有距离:

Genome1      Genome2       Dist
CP000036     CP001063       a
CP000036     CP001368       b
CP001063     CP001368       c

以上是理想的,但是重复这样输入矩阵中的每个单元格都有自己的行是完全可以的:

Genome1      Genome2       Dist
CP000036     CP000036       0
CP000036     CP001063       a
CP000036     CP001368       b
CP001063     CP000036       a
CP001063     CP001063       0
CP001063     CP001368       c
CP001368     CP000036       b
CP001368     CP001063       c
CP001368     CP001368       0

这是一个示例 3x3 矩阵,但我的数据集 I 要大得多(大约 2000x2000)。我会在 Excel 中执行此操作,但输出需要约 300 万行,而 Excel 的最大值为约 100 万行。

这个问题非常类似于“如何将 2D Excel 表格“展平”或“折叠”成 1D?1

4

1 回答 1

4

所以这是使用melt包中的一种解决方案reshape2

dm <- 
  data.frame( CP000036 = c( "0", "a", "b" ),
              CP001063 = c( "a", "0", "c" ),
              CP001368 = c( "b", "c", "0" ),
              stringsAsFactors = FALSE,
              row.names = c( "CP000036", "CP001063", "CP001368" ) )

# assuming the distance follows a metric we avoid everything below and on the diagonal
dm[ lower.tri( dm, diag = TRUE ) ]  <- NA
dm$Genome1 <- rownames( dm )

# finally melt and avoid the entries below the diagonal with na.rm = TRUE
library(reshape2) 
dm.molten <- melt( dm, na.rm= TRUE, id.vars="Genome1",
                   value.name="Dist", variable.name="Genome2" )

print( dm.molten )
   Genome1  Genome2 Dist
4 CP000036 CP001063    a
7 CP000036 CP001368    b
8 CP001063 CP001368    c

可能有更多高性能的解决方案,但我喜欢这个,因为它简单明了。

于 2013-04-25T17:54:00.307 回答