Closed Yunuuuu closed 9 months ago
I have tried to fix this by following codes, all classes work well except ConvertMatrixType
, any opinions for these?
methods::setMethod(
"[<-", c("IterableMatrix", "ANY", "ANY", "ANY"),
function(x, i, j, ..., value) {
value <- as(value, "dgCMatrix")
methods::callGeneric()
}
)
methods::setMethod(
"[<-", c("IterableMatrix", "ANY", "ANY", "dgCMatrix"),
function(x, i, j, ..., value) {
if (x@transpose) {
value <- t(methods::as(t(value), "IterableMatrix"))
} else {
value <- methods::as(value, "IterableMatrix")
}
methods::callGeneric()
}
)
methods::setMethod(
"[<-", c("IterableMatrix", "ANY", "ANY", "IterableMatrix"),
function(x, i, j, ..., value) {
i <- selection_index(i, nrow(x), rownames(x))
ni <- if (length(i) > 0) seq_len(nrow(x))[-i] else seq_len(nrow(x))
x_i <- x[i, ]
x_ni <- x[ni, ]
# dispatch the "IterableMatrix", "missing", "ANY", "IterableMatrix" method
x_i <- methods::callGeneric(x = x_i, j = j, value = value)
rbind(x_i, x_ni)[order(c(i, ni)), ]
}
)
methods::setMethod(
"[<-", c("IterableMatrix", "ANY", "missing", "IterableMatrix"),
function(x, i, j, ..., value) {
i <- selection_index(i, nrow(x), rownames(x))
ni <- if (length(i) > 0) seq_len(nrow(x))[-i] else seq_len(nrow(x))
x_i <- x[i, ]
x_ni <- x[ni, ]
if (any(dim(x_i) != dim(value))) {
stop("Mismatched dimensions in assignment to subset")
}
rownames(value) <- rownames(x_i)
colnames(value) <- colnames(x_i)
rbind(value, x_ni)[order(c(i, ni)), ]
}
)
methods::setMethod(
"[<-", c("IterableMatrix", "missing", "ANY", "IterableMatrix"),
function(x, i, j, ..., value) {
x <- t(x)
x[j, , ...] <- t(value)
t(x)
}
)
methods::setMethod(
"[<-", c("IterableMatrix", "missing", "missing", "IterableMatrix"),
function(x, i, j, ..., value) {
if (any(dim(x) != dim(value))) {
stop("Mismatched dimensions in assignment to subset")
}
rownames(value) <- rownames(x)
colnames(value) <- colnames(x)
value
}
)
The original [<-
method also gave wrong values for ConvertMatrixType
object, see https://github.com/bnprks/BPCells/issues/68 for small examples.
This should be fixed by my most recent commit 450c2b9. Please comment/reopen if you spot remaining issues.
Thanks again for finding this problem and providing such clear examples to reproduce. Sorry to not go with your suggested solution due to my code-style preferences, but I appreciate all the bugs you've been identifying
Hi, @bnprks , thanks for the fast fix, but it remains not perfect.
For some situations, [<-
will also removing names, here are some examples:
library(BPCells)
mock_matrix <- function(ngenes, ncells) {
cell.means <- 2^stats::runif(ngenes, 2, 10)
cell.disp <- 100 / cell.means + 0.5
cell.data <- matrix(stats::rnbinom(ngenes * ncells,
mu = cell.means,
size = 1 / cell.disp
), ncol = ncells)
rownames(cell.data) <- sprintf("Gene_%s", formatC(seq_len(ngenes),
width = 4, flag = 0
))
colnames(cell.data) <- sprintf("Cell_%s", formatC(seq_len(ncells),
width = 3, flag = 0
))
cell.data
}
mat <- mock_matrix(200, 200)
path <- normalizePath(tempfile(tmpdir = tempdir()), mustWork = FALSE)
obj <- BPCells::write_matrix_dir(mat = as(mat, "dgCMatrix"), dir = path)
#> Warning: Matrix compression performs poorly with non-integers.
#> • Consider calling convert_matrix_type if a compressed integer matrix is intended.
#> This message is displayed once every 8 hours.
obj <- BPCells:::rank_transform(obj, "col")
obj <- BPCells::convert_matrix_type(obj, "double")
mat <- as.matrix(obj)
#> Warning: Converting to a dense matrix may use excessive memory
#> This message is displayed once every 8 hours.
value <- matrix(sample(mat, length(mat)), nrow = nrow(mat))
obj[1:10, 1:10] <- value[1:10, 1:10]
#> Warning: cbind: column names present on some but not all matrices. Setting
#> missing names to ""
#> Warning: rbind: column names are mismatched. Setting names to match first
#> matrix
mat[1:10, 1:10] <- value[1:10, 1:10]
testthat::expect_equal(as.matrix(obj), mat)
#> Error: as.matrix(obj) not equal to `mat`.
#> Attributes: < Component "dimnames": Component 2: 190 string mismatches >
Created on 2024-02-04 with reprex v2.0.2
Thanks for following up on this. Should be fixed in commit 9e9dd2e7c
Interestingly this bug originated in some relatively new changes in [
, not in [<-
.
Hopefully this won't continue to be an unending source of bugs -- at the very least we get a new correctness test each time you find a new issue. I'll try to at least be prompt with fixes if you keep finding more problems 😅
Created on 2024-01-28 with reprex v2.0.2 ~