compare the information between two matrices R
我有两个矩阵,一个是通过删除一些行从另一个生成的。例如:
1 2 | m = matrix(1:18, 6, 3) m1 = m[c(-1, -3, -6),] |
假设我不知道 m 中的哪些行被删除来创建 m1,我应该如何通过比较两个矩阵来找到它?我想要的结果是这样的:
1 | 1, 3, 6 |
我正在处理的实际矩阵非常大。我想知道是否有任何有效的方法来进行。
这里有一些方法:
1) 如果我们可以假设
1 2 | which(tail(!duplicated(rbind(m1, m)), nrow(m))) ## [1] 1 3 6 |
2) 转置
定义
将其应用于 1:n1 中的每个 i 并从 1:n 中删除结果。
1 2 3 4 5 6 | n <- nrow(m); n1 <- nrow(m1) tm <- t(m); tm1 <- t(m1) match_indexes <- function(i) which(colSums(tm1[, i] == tm) == n1) setdiff(1:n, unlist(lapply(1:n1, match_indexes))) ## [1] 1 3 6 |
3) 计算每个矩阵的交互向量,然后使用
1 2 3 4 | i <- interaction(as.data.frame(m)) i1 <- interaction(as.data.frame(m1)) match(setdiff(i, i1), i) ## [1] 1 3 6 |
已添加如果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | m <- matrix(1:18, 6, 3) m1 <- m[c(2, 4, 5),] m <- rbind(m, m[1:2, ]) # 1 which(tail(!duplicated(rbind(m1, m)), nrow(m))) ## 1 3 6 # 2 n <- nrow(m); n1 <- nrow(m1) tm <- t(m); tm1 <- t(m1) match_indexes <- function(i) which(colSums(tm1[, i] == tm) == n1) setdiff(1:n, unlist(lapply(1:n1, match_indexes))) ## 1 3 6 7 # 3 i <- interaction(as.data.frame(m)) i1 <- interaction(as.data.frame(m1)) match(setdiff(i, i1), i) ## 1 3 6 |
一种可能的方式是将每一行表示为一个字符串:
1 2 3 4 | x1 <- apply(m, 1, paste0, collapse = ';') x2 <- apply(m1, 1, paste0, collapse = ';') which(!x1 %in% x2) # [1] 1 3 6 |
使用我的解决方案和 G. Grothendieck 的解决方案对大型矩阵进行一些基准测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | set.seed(123) m <- matrix(rnorm(20000 * 5000), nrow = 20000) m1 <- m[-sample.int(20000, 1000), ] system.time({ which(tail(!duplicated(rbind(m1, m)), nrow(m))) }) # user system elapsed # 339.888 2.368 342.204 system.time({ x1 <- apply(m, 1, paste0, collapse = ';') x2 <- apply(m1, 1, paste0, collapse = ';') which(!x1 %in% x2) }) # user system elapsed # 395.428 0.568 395.955 system({ n <- nrow(m); n1 <- nrow(m1) tm <- t(m); tm1 <- t(m1) match_indexes <- function(i) which(colSums(tm1[, i] == tm) == n1) setdiff(1:n, unlist(lapply(1:n1, match_indexes))) }) # > 15 min, not finish system({ i <- interaction(as.data.frame(m)) i1 <- interaction(as.data.frame(m1)) match(setdiff(i, i1), i) }) # run out of memory. My 32G RAM machine crashed. |
我们也可以使用
1 2 | which(!do.call(paste, as.data.frame(m)) %in% do.call(paste, as.data.frame(m1))) #[1] 1 3 6 |