【问题标题】:Altering a large distance matrix to be just three columns将大距离矩阵更改为仅三列
【发布时间】:2013-06-26 18:26:36
【问题描述】:

我有一个大型数据框/.csv,它是一个包含 42 列和 110,357,407 的矩阵。它来自两个点数据集的 x 和 y 坐标,一个具有 41,另一个具有 110,357,407,行的值表示这两组点之间的距离(列表 1 中每个点到每个点的距离)清单 2)。第一列是点列表(从 1 到 110,357,407)。下面是矩阵的摘录。

V1     V2          V3          V4         V5           V6          V7
1   38517.05    38717.8     38840.16    38961.37    39281.06    88551.03    88422.62
2   38514.05    38714.79    38837.15    38958.34    39278       88545.48    88417.09
3   38511.05    38711.79    38834.14    38955.3     39274.94    88539.92    88411.56
4   38508.05    38708.78    38831.13    38952.27    39271.88    88534.37    88406.03
5   38505.06    38705.78    38828.12    38949.24    39268.83    88528.82    88400.5
6   38502.07    38702.78    38825.12    38946.21    39265.78    88523.27    88394.97
7   38499.08    38699.78    38822.12    38943.18    39262.73    88517.72    88389.44
8   38496.09    38696.79    38819.12    38940.15    39259.68    88512.17    88383.91
9   38493.1     38693.8     38816.12    38937.13    39256.63    88506.62    88378.38
10  38490.12    38690.8     38813.12    38934.11    39253.58    88501.07    88372.85
11  38487.14    38687.81    38810.13    38931.09    39250.54    88495.52    88367.33
12  38484.16    38684.83    38807.14    38928.07    39247.5     88489.98    88361.8
13  38481.18    38681.84    38804.15    38925.06    39244.46    88484.43    88356.28
14  38478.21    38678.86    38801.16    38922.04    39241.43    88478.88    88350.75
15  38475.23    38675.88    38798.17    38919.03    39238.39    88473.34    88345.23
16  38472.26    38672.9     38795.19    38916.03    39235.36    88467.8     88339.71

我的问题是我想将此矩阵更改为 3 列,第一列类似于矩阵的第一列,有 110,357,407 行,第二列是 41 个数据点(每个都与第一个点到所有其他点的距离),第三个点是这些点之间的距离。所以它看起来像这样

Back   Pres   Dist
1          1        3486
2          1        3456
3          1        3483
4          1        3456
5          1        3429
6          1        3438
7          1        3422
8          1        3427
9          1        3428

(在back和pres的所有第一个值之间的距离完成后,pres将变为2并最终达到41)

我意识到这将输出非常荒谬的行数,但这是我运行某些 R 之外的进程所需的格式。

我尝试使用此代码

cols.Output <- data.frame(col = rep(colnames(output3), each = nrow(output3)),           
            row = rep(rownames(output3), ncol(output3)), 
            value = as.vector(output3)) 

但是每列的行数不会相同,所以我收到了一个错误(而且我认为它不能真正满足我的 pres 列需求)。我尝试使用一些 rbind.fill 和 cbind.fill 函数(plyr 中的函数和其他人在论坛中提出的函数)。我还研究了一些融合和重塑,但我对这些功能非常困惑,无法弄清楚如何适当地实现它们(或者它们是否适合我的需要)。我真的很感激这方面的任何帮助,因为我已经为此苦苦挣扎了很长时间。

编辑:只是为了更清楚地了解我需要什么。取这两个较小的数据集

返回

pres

计算这两个数据框之间的距离会生成初始矩阵:

Back       1         2         3          
1          3427      3444      3451     
2          3432      3486      3476     
3          3486      3479      3486    
4          3449      3438      3484    
5          3483      3486      3486    

我想要的输出应该是这样的:

Back        Pres        Dist
1           1           3427
2           1           3432      
3           1           3486      
4           1           3449      
5           1           3483      
1           2           3444      
2           2           3486      
3           2           3479      
4           2           3438      
5           2           3486      
1           3           3451     
2           3           3476     
3           3           3486
4           3           3484   
5           3           3486    

【问题讨论】:

  • 不清楚你想做什么。为什么不在较小的集合中显示问题。例如说,你在维度 3 mat &lt;- matrix(1:9,ncol=3,byrow=TRUE) v &lt;- -(1:3) 这个例子的预期结果是什么?

标签: r matrix distance


【解决方案1】:

是的,看起来这是通过reshape2 包中的meltcast 的某种组合通常可以解决的问题。也就是说,有 100+ 百万行,我不确定在这种情况下这是最有效的方法。

您可以按如下方式手动完成所有操作。我假设您的数据框名为df,距离在第 2 到 42 列。看看这是否有效。

d <- unlist(df[-1]) # put all the distances into a vector
newdf <- cbind(expand.grid(back=seq_len(nrow(df)), pres=seq_len(ncol(df) - 1)), d)

除非你有大量的内存,否则这可能会死。但是,对于任何简单的解决方案也是如此,因为距离向量中有 > 42 亿个元素。您可以一次处理完整数据集的子集来解决此问题。

【讨论】:

  • 终于搞定了这一切。基本上使用了这段代码,但创建了大量子集,并最终使用 data.table 包中的 rbindlist() 将它们绑定在一起。花了一些时间,而且有点混乱,但我想这就是大数据有时会发生的事情。
【解决方案2】:

下面是如何在一个小例子中使用melt

require(reshape2)
a <- matrix(rnorm(9), nrow = 3)
a[, 1] <- 1:3 ## Pretending these are one set of points
rownames(a) <- a[, 1] ## We'll put them as rownames instead of a column
melt(a[, -1]) ## And omit that column when melting

如果您有内存问题,您可以编写一个 for 循环并分段执行,完成后将每个循环写入一个文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-06
    • 2011-08-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多