2016-07-13 4 views
0

Ich habe eine Matrix R, sagen 20x20, und eine Matrix s_mat, sagen 400x2. Ich möchte jeden Untervektor der Größe 2x1 der Matrix R (gespeichert in h.help) mit jeder Reihe von s_mat vergleichen. Die Verwendung von for-Schleifen wie im folgenden Code dauert zu lange. Gibt es eine Möglichkeit, diese For-Schleifen zu vermeiden? Denn für größere Matrizen dauert es zu lange. Danke vielmals!Wie beschleunigt man Vergleich von Teilmengen von zwei Matrizen in R

library(gtools) 
R=matrix(sample(1:20,400, replace=TRUE), ncol=20, nrow=20) 
l=2 
s_mat = permutations(nrow(R), l, repeats.allowed=TRUE) 
F = numeric() 
F_perm = data.frame(matrix(NA,ncol=nrow(R)^l,nrow=nrow(R)-l+1)) 
    for (perm in 1:nrow(s_mat)) 
    { 
    s = s_mat[perm,] 
    for (k in 0:(nrow(R)-l)) 
    { 
     h = rep (TRUE, ncol(R)) 
     for (j in 1:ncol(R)) 
     { 
     h.help = R[(k+1):(k+l),j] <= s 
     if (sum(h.help)!=l) h[j]=FALSE 
     } 
     F[k+1] = sum(h)/ncol(R) 
    } 
    F_perm[perm] = F 
    } 
+0

ich den Code aktualisiert haben. Ich benutze 'h' nach der innersten Schleife. Meine erforderliche Ausgabe ist das data.frame 'F_perm' – svendula

Antwort

0

Ich denke, das die Arbeit machen wird:

set.seed(1L); 
NV <- 20L; R.NR <- 20L; R.NC <- 20L; NP <- 2L; 
R <- matrix(sample(NV,R.NR*R.NC,T),R.NR); 
s_mat <- unname(as.matrix(do.call(expand.grid,rep(list(seq_len(NV)),NP)))); 
F_perm <- matrix(NA_real_,R.NR-NP+1L,nrow(s_mat)); 
for (sri in seq_len(nrow(s_mat))) { 
    s <- s_mat[sri,]; 
    F_perm[,sri] <- rowSums(Reduce(`&`,Map(function(e,i) R[i:(nrow(R)-length(s)+i),]<=e,s,seq_along(s))))/ncol(R); 
}; ## end for 
+0

Vielen Dank @bgoldst, brilliant, das ist viel schneller !! Ich bin nicht sicher, wie man Berechnung von 'F' und 'F_perm' einbaut (sehen Sie meinen aktualisierten meinen Code). Können Sie bitte helfen? – svendula

+0

@svendula Danke. Siehe Bearbeiten. – bgoldst

+0

Danke, seltsam, die Ausgabe von meinem 'F_perm' und dein' F_perm' sind nicht identisch. Aber ich sehe das Problem nicht. Irgendwelche Ideen? – svendula