将 x、y、z 的大型平面文件读入行名 x、列名 y 和值 z 的 table

Reading large flat file of x,y,z into table of row names x, column names y, and values z

最近我开始使用 R,我想用它根据信息的变化将大量条件概率文件转换为距离矩阵(参见:https://en.wikipedia.org/wiki/Variation_of_information and https://en.wikipedia.org/wiki/Mutual_information)为此,我发现我需要读取一个相当大的平面文件 (~35GB) 的条件概率,其内容是:

     1      7979  1
     2     23243  0
     23243     1  0.343
     ......

等等。我想要做的是读取数据并以这样的方式重塑我有一个 table (或矩阵)具有:

        1  2  ... 7979 ... 23243 ...
 1      z  z   z   1   z    z ... 
 2      z  z   z   z   z    0 ...
...     z  z   z   z   z    z ...
7979    z  z   z   z   z    z ...
...     z  z   z   z   z    z ...
23243  0.343 0   z   z   z    z ...

其中 z 是平面文件的第三列。需要考虑的事项:

1)平面文件第三列的大部分值为0。

2) 结果 table 是正方形,每行大约有 50,000 个条目。

3) 加载 table 后,必须对每一行求和多次,对所有元素求和一次,然后 (#rows-1)^2 次,每次添加一列求和。

任何想法都会很棒。到目前为止我唯一的想法是在预处理步骤中删除平面文件中第三列等于零的所有行(awk 做得很好)然后尝试找到一个包来创建一个稀疏矩阵从平面文件并将其转换为 R 中的动态密集矩阵以进行计算,但我运气不佳(我知道 dummy.matrix 会做类似的事情,但我不确定如何使用它) .

示例数据

创建一个只有非零 z 值的数据框(假设我们可以在导入数据之前从平面文件中删除所有零行)。

N <- 50000
S <- N * 0.8 
df_input <- data.frame( x = sample(1:N, S), y = sample(1:N, S), z = runif(S))

# > head(df_input)
#      v1    v2     value
# 1 35093 13107 0.6078230
# 2 46104  5201 0.1596800
# 3 21262  1943 0.9006491
# 4 10250 21508 0.6725270
# 5 41243 33452 0.7160704
# 6 17123 45607 0.5535252

创建矩阵

使用 Matrix 包我们可以表示稀疏矩阵:

# create sparse matrix
library(Matrix)
M1 <- sparseMatrix(i = df_input[,1], j = df_input[,2], x = df_input$z, dims = c(N,N))

# > dim(M1)
# [1] 50000 50000

计算总和

对于较小的矩阵,我们通常会这样做:

# sum rows with i-th column excluded 
# *warning: you need a memory for N*(N+1) matrix!*
result <- sapply(1:(N + 1), FUN = function(i) {
  rowSums(M1[,-i])
})

但可能无法在内存中创建 N x (N+1) 矩阵。 M1 是稀疏的,但生成的 N x (N+1) 矩阵充满了和值。现在怎么办?

好吧,这取决于这笔款项将如何使用。您始终可以从源 M1 稀疏矩阵中获取包含排除列的行的总和:

rsums <- function(M1, col_num) rowSums(M1[,-col_num])

没有第 i 列的总和:

rsums(M1, i)

j 行没有第 i 列的总和:

rsums(M1, i)[j]