2013-04-29 8 views
5

Diese Frage ähnelt Fragen, die in anderen Sprachen bezüglich Gleitkommafehler gestellt wurden (zB here), aber ich habe keine befriedigende Lösung gefunden.Wie entferne ich Matrizen aus einer Liste, die Duplikate innerhalb eines Gleitkommafehlers sind?

Ich arbeite an einem Projekt, das die Untersuchung von Matrizen mit bestimmten Eigenschaften beinhaltet. Als Teil davon muss ich wissen, wie viele Matrizen in einer Liste einzigartig sind.

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))) 

Diese Liste wird dann auf die Elemente von samples_list anhand von Berechnungen aus den Daten gefüllt. Nachdem mat_list ausgefüllt wurde, muss ich Duplikate entfernen. Running

mat_list <- unique(mat_list) 

engt die Dinge ziemlich ein wenig; Viele dieser Elemente befinden sich jedoch tatsächlich innerhalb eines Maschinenfehlers voneinander. Die Funktion unique erlaubt es nicht, Genauigkeit anzugeben, und ich konnte den Quellcode für die Änderung nicht finden.

Eine Idee war ich dies hatte:

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) 
} 

aber das sieht nur paarweise Unterschiede. Es wäre einfach, aber höchstwahrscheinlich ineffizient, dies mit verschachtelten for Loops zu tun.

Welche Methoden kennen Sie oder welche Ideen haben Sie, um das Problem zu lösen, Matrizen zu identifizieren und zu entfernen, die sich im Maschinenfehler befinden und Duplikate sind?

+0

Können Sie ein paar Beispiele veröffentlichen, wo Sie die Antwort denken ist "gleich" und "ungleich" und spezifizieren warum? Im Moment haben Sie "Datenquelle", aber niemand sonst. Wir empfehlen die Verwendung von 'dput (mat)'. –

Antwort

6

Hier ist eine Funktion, die all.equal jedes Paar outer Verwendung gilt und entfernt alle Duplikate:

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] 
} 

Ein Beispiel:

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

Das ist eine nette Codierung! –

+0

Das ist ein interessanter Ansatz, mir war die "all.equal" -Funktion nicht bekannt. Es scheint eine Menge Speicher zu verwenden: Versuchen Sie, es auf einer Reihe von Matrizen der Dimension 360x300 zu verwenden, und Sie werden sehen, was ich meine. Zum Beispiel: 'M1 <- Matrix (Daten = 0, nrow = 360, ncol = 300); M2 <- M1 + rep (1e-17.300); alle <- Liste (M1, M2); all <- rep (alle, 30) 'Das sollte erkennen, dass sie alle eine Nullmatrix sind, aber mein Computer (mit 12 GB RAM) kann damit nicht umgehen. –

+0

@D_Watkins, habe ich meine Antwort leicht bearbeitet. Die Änderung sollte den Speicher besser nutzen. – flodel

1

Ich glaube, dass Sie nach all.equal suchen, die Objekte 'innerhalb des Maschinenfehlers' vergleicht. Überprüfen Sie ?all.equal.

Verwandte Themen