标记矩阵中包含相同值集

时间:2017-03-09 16:30:22

标签: r matrix

我有一个整数矩阵

m <- rbind(c(1,2),
           c(3,6),
           c(5,1),
           c(2,1),
           c(6,3))

我正在寻找一个函数,它将此矩阵作为输入,并输出一个带有flag的向量length(flag) == ncol(m),它将包含相同唯一整数的行分配为相同的唯一(假设为整数)值。

对于上面的示例,所需的输出将是:

flag <- c(1, 2, 3, 1, 2)

因此m中的第1行和第4行获得相同的标志1,因为它们都包含相同的整数集,在本例中为{1,2}。同样,第2行和第5行也会获得相同的标记。

该解决方案适用于任意数量的列。

我唯一能想到的是以下方法......

FlagSymmetric <- function(x) {

  vec_sim <- rep(NA, nrow(x)) # object containing flags
  ind_ord <- ncol(x)

  counter <- 1

  for(i in 1:nrow(x)) {

    if(is.na(vec_sim[i])) { # if that row is not flagged yet, proceed ...

      vec_sim[i] <- counter # ... and give the next free flag

      for(j in (i+1):nrow(x)) {

        if( (i+1) > nrow(x) ) next # in case of tiny matrices

        ind <- x[j, ] %in% x[i, ] 
        if(sum(ind)==ind_ord) vec_sim[j] <- counter # if the same, assign flag

      }

      counter <- counter + 1

    }
  }

  return(vec_sim)
}

......这就是我想要的:

> FlagSymmetric(m)
[1] 1 2 3 1 2

如果n = nrow(m)这需要1/2 n ^ 2次操作。当然,我可以通过在C ++中编写它来更快地完成它,但这只能在一定程度上缓解我的问题,因为我正在处理具有潜在大量行的矩阵。

我想必须有更明智的方法来做到这一点。

修改

另外一个更一般的例子(排序行和粘贴到字符串不可能):

m2 <- rbind(c(1,112),
           c(11,12),
           c(12,11),
           c(112,1),
           c(6,3))

flag2 <- c(1, 2, 2, 1, 3) # desired output

FlagSymmetric(m2) # works
[1] 1 2 2 1 3 

1 个答案:

答案 0 :(得分:2)

假设您的矩阵中只有数字数据。

首先将矩阵转换为数据帧,

m <- data.frame(m)

我们可以sort每一行和paste他们在一起。将它们转换为factor,然后转换为numeric以获取每个组合的唯一数字

m$flag <- as.numeric(factor(apply(m, 1, function(x) paste0(sort(x), collapse = ""))))
m

#  X1 X2 flag
#1  1  2    1
#2  3  6    3
#3  5  1    2
#4  2  1    1
#5  6  3    3

修改

上述解决方案不适用于新示例中所述的每种组合。为了区分每个数字,如@d.b所述,我们可以使用任何非空的崩溃参数。有关更新示例,

as.numeric(factor(apply(m2, 1, function(x) paste0(sort(x), collapse = "-"))))

#[1] 1 2 2 1 3