我有以下数据
margin1 <- c(72,34,446,40,33,71,2,96)
margin2 <- c(70,36,455,41,36,56,2,98)
propabilities <- matrix(1/8,8,8)
现在,我想通过乘以以下逻辑来填充8x8矩阵的内部单元格
matrix <- matrix(0,8,8)
matrix[1,] <- probabilities[1,]*margin2[1]
matrix[2,] <- probabilities[2,]*margin2[2]
matrix[3,] <- probabilities[3,]*margin2[3]
matrix[4,] <- probabilities[4,]*margin2[4]
matrix[5,] <- probabilities[5,]*margin2[5]
matrix[6,] <- probabilities[6,]*margin2[6]
matrix[7,] <- probabilities[7,]*margin2[7]
matrix[8,] <- probabilities[8,]*margin2[8]
但是,让这个问题变得困难的是,内部单元应该始终是整数。因此,我编写了以下舍入函数:
rounding <- function(x) {
output <- matrix(0,8,8)
for(i in 1:nrow(x)){
obj <- x[i,]
y <- floor(obj)
indices <- tail(order(obj-y), round(sum(obj)) - sum(y))
y[indices] <- y[indices] + 1
output[i,]<- y
}
x <- output
return(x)
}
我的预期输出如下:
matrix <- rounding(matrix)
尽管这样做可以确保矩阵对象的rowSums等于margin2,但colSums不等于margin1。但是,这正是我所需要的。有什么方法可以重写舍入函数,可以达到目的吗?
答案 0 :(得分:1)
只要我正确理解了您,描述的问题就是这个问题,即如何根据给定的行和列总和(即所谓的“边距”)填充矩阵。
在您的特定情况下,您尝试填充8x8矩阵。由于您有64个未知数,但是8 + 8-1 = 15个独立方程(8个行总和,8个列总和,减去1,因为行和的 sum 必须等于列的总和总结)最重要的是,不存在唯一的解决方案,相反会有很多。
如果矩阵值可以是有理数,则可以为行margin2_i * margin1_j / sum(margin2)
和列i
或R
mat <- margin2 %*% t(margin1) / sum(margin1)
mat
# [,1] [,2] [,3] [,4] [,5] [,6]
#[1,] 6.3476071 2.99748111 39.319899 3.5264484 2.90931990 6.2594458
#[2,] 3.2644836 1.54156171 20.221662 1.8136020 1.49622166 3.2191436
#[3,] 41.2594458 19.48362720 255.579345 22.9219144 18.91057935 40.6863980
#[4,] 3.7178841 1.75566751 23.030227 2.0654912 1.70403023 3.6662469
#[5,] 3.2644836 1.54156171 20.221662 1.8136020 1.49622166 3.2191436
#[6,] 5.0780856 2.39798489 31.455919 2.8211587 2.32745592 5.0075567
#[7,] 0.1813602 0.08564232 1.123426 0.1007557 0.08312343 0.1788413
#[8,] 8.8866499 4.19647355 55.047859 4.9370277 4.07304786 8.7632242
# [,7] [,8]
#[1,] 0.176322418 8.4634761
#[2,] 0.090680101 4.3526448
#[3,] 1.146095718 55.0125945
#[4,] 0.103274559 4.9571788
#[5,] 0.090680101 4.3526448
#[6,] 0.141057935 6.7707809
#[7,] 0.005037783 0.2418136
#[8,] 0.246851385 11.8488665
我们可以确认确实如此
mat
的行总和等于margin2
identical(rowSums(mat), margin2)
#[1] TRUE
那
mat
的列总和等于margin1
identical(colSums(mat), margin1)
#[1] TRUE
如果要将矩阵值限制为仅整数值,则问题会更加复杂。在这里,我将向您介绍说明迭代解决方案策略的excellent post on Mathematics。