我有一个整数矩阵
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
答案 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