| Type: | Package | 
| Title: | Matrix Balancing and Rounding | 
| Version: | 1.0.0 | 
| Description: | Balancing and rounding matrices subject to restrictions. Adjustment of matrices so that columns and rows add up to given vectors, rounding of a matrix while keeping the column and/or row totals, performing these by blocks... | 
| License: | GPL (≥ 3) | 
| Encoding: | UTF-8 | 
| RoxygenNote: | 7.3.2 | 
| Imports: | CVXR, dplyr, methods, utils | 
| URL: | https://mserrano-ine.github.io/cuadramelo/ | 
| Suggests: | knitr, rmarkdown | 
| VignetteBuilder: | knitr | 
| Depends: | R (≥ 2.10) | 
| NeedsCompilation: | no | 
| Packaged: | 2024-10-07 06:39:22 UTC; U853802 | 
| Author: | Miguel Serrano [aut, cre] | 
| Maintainer: | Miguel Serrano <miguel.serrano.martin@ine.es> | 
| Repository: | CRAN | 
| Date/Publication: | 2024-10-10 16:20:11 UTC | 
cuadramelo: Matrix Balancing and Rounding
Description
 
Balancing and rounding matrices subject to restrictions. Adjustment of matrices so that columns and rows add up to given vectors, rounding of a matrix while keeping the column and/or row totals, performing these by blocks...
Author(s)
Maintainer: Miguel Serrano miguel.serrano.martin@ine.es
See Also
Useful links:
Modify matrix by blocks
Description
Applies a function to a matrix by horizontal or vertical blocks.
Usage
apply_by_block(Y, layout, L, FUN, ...)
Arguments
| Y | Matrix | 
| layout | Blocks are distributed: 1 horizontally, 2 vertically. | 
| L | Number of lines of the block. | 
| FUN | Funtion to apply to the block. | 
| ... | Arguments to be passed to FUN. | 
Value
A matrix.
Balance matrix by blocks
Description
Applies balance_matrix() to equally-sized blocks that partition the
matrix either vertically or horizontally.
Usage
balance_by_blocks(Y, col_totals = NULL, row_totals = NULL, layout, L)
Arguments
| Y | Matrix to be balanced. | 
| col_totals | Desired colSums for each block. See details. | 
| row_totals | Desired rowSums for each block. See details. | 
| layout | The blocks are distributed: 1 horizontally, 2 vertically. | 
| L | Number of lines that a block encompasses. | 
Details
When Y is composed of **vertically** stacked blocks, col_totals must be a matrix whose rows are the colSums for each block, and row_totals just a (vertical) vector.
When Y is composed of blocks arraged **horizontally**, col_totals is a (horizontal) vector, and row_totals is a matrix whose columns are the rowSums for each block.
Value
The balanced matrix.
Examples
set.seed(10)
Y <- (rnorm(32)*10) |> matrix(ncol = 2) |> round(3)
v <- aggregate(Y, by = list(rep(1:4, times = rep(4,4))), FUN = sum)[, -1] |>
  round() |> as.matrix()
X <- balance_by_blocks(Y, v, layout = 2, L = 4)
U <- Y[5:8,] |> balance_matrix(v[2,])
X[5:8,] - U
Balance matrix
Description
Balances a matrix so that the columns and/or rows add up to a certain vector.
Usage
balance_matrix(Y, col_totals = NULL, row_totals = NULL, allow_negative = TRUE)
Arguments
| Y | Matrix to be balanced. | 
| col_totals | (optional) Desired sum of columns. | 
| row_totals | (optional) Desired sum of rows. | 
| allow_negative | Are negative entries in the balanced matrix allowed? | 
Details
Balancing is done according to the criteria of minimum sum of squares.
If neither col_totals nor row_totals is given, the same matrix will be
returned. If only one of them is given, only that axis will be
balanced.
Value
The balanced matrix.
Examples
set.seed(2)
Y <- rnorm(3*5) |> matrix(3,5) |> round(3)
v <- c( 0.876, -1.078, 3.452, 0.261, 1.349)
h <- c(-1.851, 0.243, 6.468)
X1 <- balance_matrix(Y, v, h)
Y
X1
h
rowSums(X1)
v
colSums(X1)
X3 <- balance_matrix(Y, col_totals = v)
v
colSums(X3)
X4 <- balance_matrix(Y, row_totals = h)
h
rowSums(X4)
Make non-negative
Description
Modifies as little as possible the entries of a matrix in order to make them non-negative, keeping row and column totals unchanged.
Usage
make_non_negative(Y, allowSlack = FALSE)
Arguments
| Y | Matrix to be positivized. | 
| allowSlack | Can colSums and rowSums be modified? | 
Value
A non-negative matrix, except if it is impossible to balance the matrix.
Examples
Y <- c(1,2,-1,1,
       2,2,3,1,
       1,1,-2,3) |>
       matrix(nrow = 3)
X <- make_non_negative(Y)
Y
X |> round(2)
rowSums(Y)
rowSums(X)
colSums(Y)
colSums(X)
set.seed(2)
Y <- rnorm(3*5) |> matrix(3,5) |> round(3)
Y
tryCatch(make_non_negative(Y), error = function(e) {
  print(e)
})
make_non_negative(Y, allowSlack = TRUE) |> round()
Round matrix by blocks
Description
Applies round_matrix() to equally-sized blocks that partition the
matrix either vertically or horizontally.
Usage
round_by_blocks(Y, layout, L, digits = 0, MARGIN_BLOCK = 0)
Arguments
| Y | Matrix. | 
| layout | The blocks are distributed: 1 horizontally, 2 vertically. | 
| L | Number of lines that a block encompasses. | 
| digits | Number of decimal places to be rounded to. | 
| MARGIN_BLOCK | For each block 
 | 
Value
The rounded matrix.
Examples
set.seed(10)
Y <- (rnorm(32)*10) |> matrix(ncol = 2) |> round(3)
X <- round_by_blocks(Y, 2, 4)
U <- Y[5:8,] |> round_matrix()
X[5:8,] - U
Round a matrix
Description
Returns an integer matrix that preserves the rounded colSums and rowSums.
Usage
round_matrix(Y, digits = 0, MARGIN = 0)
Arguments
| Y | A matrix. | 
| digits | Decimal places to round to. | 
| MARGIN | One of 
 | 
Details
The function will throw a *warning* if the problem is infeasable. To be able to round the matrix in this fashion, the following things must be equal:
-  the sum of the differences between the row totals and the rounded row totals 
-  the sum of the differences between the column totals and the rounded row totals 
Value
The rounded matrix.
Examples
set.seed(6)
Y <- rnorm(3*5)*10 |> matrix(3,5) |> round(3)
X <- round_matrix(Y)
Y
X
colSums(Y) |> round()
colSums(X)
rowSums(Y) |> round()
rowSums(X)
Round univariate
Description
Rounds a vector preserving the rounded sum.
Usage
round_vector(x, digits = 0)
Arguments
| x | A vector. | 
| digits | Number of decimal places to be rounded to. | 
Value
description
Examples
set.seed(4)
x <- (rnorm(5)*10) |> abs()
y <- round_vector(x)
cbind(x, y)
round(sum(x)) - sum(y)