2013-04-29 56 views
5

这个问题类似于其他语言中有关浮点错误的问题(例如here),但是我还没有找到令人满意的解决方案。如何从浮点错误中重复的列表中删除矩阵?

我正在研究一个项目,涉及调查共享某些特征的矩阵。作为其中的一部分,我需要知道列表中有多少个矩阵是唯一的。

D <- as.matrix(read.table("datasource",...)) 
mat_list <- vector('list',length=length(samples_list)) 
mat_list <- lapply(1:length(samples_list),function(i) matrix(data=0,nrow(D),ncol(D))) 

该列表然后,通过从基于的samples_list的元素中的数据计算填充。在mat_list已填充后,我需要删除重复项。运行

mat_list <- unique(mat_list) 

把事情缩小了很多;然而,这些元素中的很多都是真的在彼此的机器错误之内。函数unique不允许指定精度,并且我无法找到用于修改的源代码。

我有一个想法是这样的:

ErrorReduction<-function(mat_list, tol=2){ 
    len <- length(mat_list) 
    diff <- mat_list[[i]]-mat_list[[i+1]] 
    for(i in 1:len-1){ 
    if(norm(diff,"i")<tol){ 
    mat_list[[i+1]] <- mat_list[i] 
    } 
    } 
    mat_list<-unique(mat_list) 
    return(mat_list) 
} 

但这只是着眼于配对差异。这很简单,但最有可能效率低下嵌套for循环。

你知道什么方法,或者你有什么想法,来处理识别和删除重复机器错误中的矩阵的问题?

+0

你可以发布一个情况下你认为答案是例子“平等”和“不平等”并指明原因?目前你有“数据源”,但没有其他人。我们鼓励使用'dput(mat)'。 – 2013-04-29 23:55:05

回答

6

这里是适用all.equal使用outer每对,并删除所有重复的功能:

approx.unique <- function(l) { 
    is.equal.fun <- function(i, j)isTRUE(all.equal(norm(l[[i]] - l[[j]], "M"), 0)) 
    is.equal.mat <- outer(seq_along(l), seq_along(l), Vectorize(is.equal.fun)) 
    is.duplicate <- colSums(is.equal.mat * upper.tri(is.equal.mat)) > 0 
    l[!is.duplicate] 
} 

一个例子:

a <- matrix(runif(12), 4, 3) 
b <- matrix(runif(12), 4, 3) 
c <- matrix(runif(12), 4, 3) 

all <- list(a1 = a, b1 = b, a2 = a, a3 = a, b2 = b, c1 = c) 

names(approx.unique(all)) 
# [1] "a1" "b1" "c1" 
+0

这是一些不错的编码! – 2013-04-30 00:23:14

+0

这是一个有趣的方法,我不知道'all.equal'函数。它似乎使用了很多内存:尝试在一组尺寸为360x300的矩阵上使用它,并且您会明白我的意思。例如: 'M1 < - 矩阵(数据= 0,nrow = 360,ncol = 300); M2 < - M1 + rep(1e-17,300); M2 < - M1 + rep(1e-17,300); all < - list(M1,M2); all < - rep(all,30)'这应该认识到它们都是零矩阵,但是我的电脑(具有12 Gb RAM)无法处理它。 – 2013-04-30 16:45:55

+0

@D_Watkins,我稍微编辑了我的答案。改变应该更好地利用内存。 – flodel 2013-04-30 17:05:55

1

我相信你正在寻找all.equal比较对象'机器内部错误'。检出?all.equal