避免在矩阵乘法中传播 NA
Avoid propagation of NA in matrix multiplication
我在矩阵乘法的上下文中传播缺失值时遇到了一些困难。
我的第一个矩阵 X
是 5 个流量计每小时的气体流量测量值:
X=structure(c(16, 19, 28, 32, 30, 22, 16, 13, 8, 6, 5, 3, 5, 5, 6, 13, 7, 10, 4, 2, 1, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 4, -16, -17, -20, -31, -25, -25, -16, -12, -13, -15, -9, -7), .Dim = c(12L, 5L), .Dimnames = list(NULL, c("meter1", "meter2", "meter3", "meter4", "meter5")))
#### meter1 meter2 meter3 meter4 meter5
#### [1,] 16 5 0 7 -16
#### [2,] 19 5 0 8 -17
#### ...
我的第二个矩阵 Z
说明这些天然气流量是如何分配给 4 个城市的:例如(Z
的第一列),对于 city1,总净流量定义为(1)*Meter1 + (-1)*Meter2 + (1)*Meter5
。
Z=structure(c(1, -1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0), .Dim = c(5L, 4L), .Dimnames = list(NULL, c("city1", "city2", "city3", "city4")))
#### city1 city2 city3 city4
#### [1,] 1 0 0 0
#### [2,] -1 1 0 0
#### [3,] 0 1 0 0
#### [4,] 0 0 1 0
#### [5,] 1 0 0 0
所以要计算每个城市的净流量,我只需要进行矩阵乘法:
X %*% Z
#### city1 city2 city3 city4
#### [1,] -5 5 7 0
#### [2,] -3 5 8 0
#### ...
我的问题是我的 X
matrix 中有很多 缺失值(这里是 9 NA
):
set.seed(3); for (i in 1:10) X[sample.int(nrow(X), 1), sample.int(ncol(X), 1)] <- NA
当我进行矩阵乘法时,NA
传播到整行,即使它位于零值列(这不会影响总和)。所以乘法后我得到 24 NA
。但是,如果我只使用非空的仪表逐个城市进行计算,我只会得到 11 NA
:
sum(is.na(cbind(X[, 1] - X[, 2] + X[, 5], X[, 2] + X[, 3], X[, 4], 0)))
#### [1] 11
我想知道是否有一种方法 可以计算每个城市的流量,而不会传播我的 NA
。在现实中,我的矩阵要大得多,但一个城市的长度永远不会超过 4 米(相当稀疏)。我想避免手动对每一列进行编码(因为如果网络发生任何变化,脚本将不再起作用)。
谢谢,
是的,我确定这就是您需要的:
library(Matrix)
ZZ <- Matrix(Z, sparse = TRUE)
X %*% ZZ
#12 x 4 Matrix of class "dgeMatrix"
# city1 city2 city3 city4
# [1,] -5 5 7 0
# [2,] NA NA NA 0
# [3,] NA 6 8 0
# [4,] -12 13 7 0
# [5,] NA NA 7 0
# [6,] -13 10 6 0
# [7,] -4 NA NA 0
# [8,] -1 2 NA 0
# [9,] -6 1 5 0
#[10,] -11 2 4 0
#[11,] NA NA 4 0
#[12,] -5 1 4 0
如你所料,只有11个NA
。
跟进
It throws an error when I try to convert the result to a data frame: data.frame(X %*% ZZ)
. How can I do it?
使用data.frame(as.matrix(X %*% ZZ))
.
我在矩阵乘法的上下文中传播缺失值时遇到了一些困难。
我的第一个矩阵 X
是 5 个流量计每小时的气体流量测量值:
X=structure(c(16, 19, 28, 32, 30, 22, 16, 13, 8, 6, 5, 3, 5, 5, 6, 13, 7, 10, 4, 2, 1, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 4, -16, -17, -20, -31, -25, -25, -16, -12, -13, -15, -9, -7), .Dim = c(12L, 5L), .Dimnames = list(NULL, c("meter1", "meter2", "meter3", "meter4", "meter5")))
#### meter1 meter2 meter3 meter4 meter5
#### [1,] 16 5 0 7 -16
#### [2,] 19 5 0 8 -17
#### ...
我的第二个矩阵 Z
说明这些天然气流量是如何分配给 4 个城市的:例如(Z
的第一列),对于 city1,总净流量定义为(1)*Meter1 + (-1)*Meter2 + (1)*Meter5
。
Z=structure(c(1, -1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0), .Dim = c(5L, 4L), .Dimnames = list(NULL, c("city1", "city2", "city3", "city4")))
#### city1 city2 city3 city4
#### [1,] 1 0 0 0
#### [2,] -1 1 0 0
#### [3,] 0 1 0 0
#### [4,] 0 0 1 0
#### [5,] 1 0 0 0
所以要计算每个城市的净流量,我只需要进行矩阵乘法:
X %*% Z
#### city1 city2 city3 city4
#### [1,] -5 5 7 0
#### [2,] -3 5 8 0
#### ...
我的问题是我的 X
matrix 中有很多 缺失值(这里是 9 NA
):
set.seed(3); for (i in 1:10) X[sample.int(nrow(X), 1), sample.int(ncol(X), 1)] <- NA
当我进行矩阵乘法时,NA
传播到整行,即使它位于零值列(这不会影响总和)。所以乘法后我得到 24 NA
。但是,如果我只使用非空的仪表逐个城市进行计算,我只会得到 11 NA
:
sum(is.na(cbind(X[, 1] - X[, 2] + X[, 5], X[, 2] + X[, 3], X[, 4], 0)))
#### [1] 11
我想知道是否有一种方法 可以计算每个城市的流量,而不会传播我的 NA
。在现实中,我的矩阵要大得多,但一个城市的长度永远不会超过 4 米(相当稀疏)。我想避免手动对每一列进行编码(因为如果网络发生任何变化,脚本将不再起作用)。
谢谢,
是的,我确定这就是您需要的:
library(Matrix)
ZZ <- Matrix(Z, sparse = TRUE)
X %*% ZZ
#12 x 4 Matrix of class "dgeMatrix"
# city1 city2 city3 city4
# [1,] -5 5 7 0
# [2,] NA NA NA 0
# [3,] NA 6 8 0
# [4,] -12 13 7 0
# [5,] NA NA 7 0
# [6,] -13 10 6 0
# [7,] -4 NA NA 0
# [8,] -1 2 NA 0
# [9,] -6 1 5 0
#[10,] -11 2 4 0
#[11,] NA NA 4 0
#[12,] -5 1 4 0
如你所料,只有11个NA
。
跟进
It throws an error when I try to convert the result to a data frame:
data.frame(X %*% ZZ)
. How can I do it?
使用data.frame(as.matrix(X %*% ZZ))
.