R中矩阵的任意两列之间的相同元素的最大数量

时间:2016-08-14 11:19:07

标签: r matrix

我只是想知道是否有一种简单的方法来计算R中任何两​​列矩阵之间相同元素的最大数量。

例如,我有一个矩阵

test <- replicate(10, sample((0:3), 10, replace = TRUE))

test

      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    3    0    1    0    2    2    1    0    2     0
 [2,]    1    1    3    2    0    2    3    0    2     2
 [3,]    2    3    0    0    1    2    0    3    0     2
 [4,]    2    2    1    1    2    0    0    1    1     0
 [5,]    2    0    1    2    0    1    1    1    0     0
 [6,]    1    0    1    3    2    3    3    1    3     2
 [7,]    0    1    3    2    1    0    1    2    1     1
 [8,]    0    3    1    3    0    2    3    1    1     1
 [9,]    2    3    1    3    0    1    0    1    3     2
[10,]    3    2    1    0    2    1    3    2    3     1

要比较第1列和第2列,我使用

table(test[,1] == test[,2])

FALSE  TRUE 
    8     2 

因此这两列之间有两个相同的元素。

我现在可以使用两个嵌套for循环对所有列对重复此操作,然后找到最大TRUE调用数,但这看起来不太好。谁能想到更好的方法?

干杯,

MAIK

2 个答案:

答案 0 :(得分:3)

看到一个合理的答案被拒绝总是很有趣。虽然我不喜欢这个减去分数,但我会保留我的答案。选民,您怎么看?

让我们首先获得一些可重复的玩具数据:

set.seed(0); x <- replicate(10, sample((0:3), 10, replace = TRUE))
#      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,]    3    0    3    1    1    2    1    3    3     0
# [2,]    1    0    3    1    3    1    3    1    1     0
# [3,]    1    0    0    2    2    3    1    3    2     0
# [4,]    2    2    2    1    3    1    1    1    1     2
# [5,]    3    1    0    0    2    0    1    1    1     3
# [6,]    0    3    1    3    2    0    2    1    3     3
# [7,]    3    1    1    2    3    0    1    3    0     3
# [8,]    3    2    0    3    0    1    1    3    2     1
# [9,]    2    3    1    0    1    2    3    1    0     1
#[10,]    2    1    3    2    2    2    0    3    0     3

对于任何输入矩阵x,您可以使用:

y <- unlist(lapply(seq_len(ncol(x)-1L),
                   function(i) colSums(x[, (i+1):ncol(x), drop = FALSE] == x[, i])))
# [1] 1 2 3 2 4 1 4 2 3 3 1 0 0 3 1 3 5 1 3 1 2 4 1 4 3 4 2 3 5 1 1 3 2 1 2 2 3 3
#[39] 1 2 3 1 4 3 1
max(y)
# [1] 5

@David的评论基本上是做同样的事情但速度慢了

y <- combn(ncol(x), 2, FUN = function(u) sum(x[, u[1]] == x[, u[2]]))
# [1] 1 2 3 2 4 1 4 2 3 3 1 0 0 3 1 3 5 1 3 1 2 4 1 4 3 4 2 3 5 1 1 3 2 1 2 2 3 3
#[39] 1 2 3 1 4 3 1
max(y)
# [1] 5

<强>基准

我们生成一个10 * 1000矩阵用于实验:

set.seed(0); x <- replicate(1e+3, sample((0:3), 10, replace = TRUE))
system.time(unlist(lapply(seq_len(ncol(x)-1L), function(i) colSums(x[, (i+1):ncol(x), drop = FALSE] == x[, i]))))
#   user  system elapsed 
#  0.176   0.032   0.207 
system.time(combn(ncol(x), 2, FUN = function(u) sum(x[, u[1]] == x[, u[2]])))
#   user  system elapsed 
#  4.692   0.008   4.708 

类似于距离矩阵?

有了这个想法,你也可以产生一个&#34;距离&#34;所有列之间不等于元素数量的矩阵(只需将==替换为!=):

y <- unlist(lapply(seq_len(ncol(x)-1L),
                   function(i) colSums(x[, (i+1):ncol(x), drop = FALSE] != x[, i])))
z <- matrix(0L, ncol(x), ncol(x))
z[lower.tri(z)] <- y
#      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,]    0    0    0    0    0    0    0    0    0     0
# [2,]    9    0    0    0    0    0    0    0    0     0
# [3,]    8    7    0    0    0    0    0    0    0     0
# [4,]    7    9    9    0    0    0    0    0    0     0
# [5,]    8   10    7    7    0    0    0    0    0     0
# [6,]    6   10    9    6    9    0    0    0    0     0
# [7,]    9    7    8    8    7    8    0    0    0     0
# [8,]    6    9    6    7    8    7    8    0    0     0
# [9,]    8    7    9    5    9    7    7    6    0     0
#[10,]    7    5    6    9    8    9    9    7    9     0

请注意,由于对称性,仅计算下三角矩阵。对角线都是零(或过程)。

答案 1 :(得分:2)

尝试:

max(combn(split(test, col(test)), 2, function(x) sum(x[[1]] == x[[2]])))

如果你想知道哪一对具有最多的相等元素,那就更复杂了。