Wie kann ich eine verschachtelte Schleife mit lapply in R ersetzen?
Guten Tag ,
Ich habe diese R-Funktion entwickelt, die Daten in Buckets hasht:
# The used packages
library("pacman")
pacman::p_load(dplyr, tidyr, devtools, MASS, pracma, mvtnorm, interval, intervals)
pacman::p_load(sprof, RDocumentation, helpRFunctions, foreach , philentropy , Rcpp , RcppAlgos)
hash<-function(v,p){
if(dot(v,p)>0) return(1) else (0) }
LSH_Band<-function(data,K ){
# We retrieve numerical columns of data
t<-list.df.var.types(data)
df.r<-as.matrix(data[c(t$numeric,t$Intervals)])
n=nrow(df.r)
# we create K*K matrice using normal law
rn=array(rnorm(K*K,0,1),c(K,K))
# we create K*K matrice of integers using uniform law , integrs are unique in each column
rd=unique.array(array(unique(ceiling(runif(K*K,0,ncol(df.r)))),c(K,K)))
buckets<-array(NA,c(K,n))
for (i in 1:K) {
for (j in 1:n) {
buckets[i,j]<-hash(df.r[j,][rd[,i]],rn[,i])
}
}
return(buckets)
}
> df.r
age height salaire.1 salaire.2
1 27 180 0 5000
2 26 178 0 5000
3 30 190 7000 10000
4 31 185 7000 10000
5 31 187 7000 10000
6 38 160 10000 15000
7 39 158 10000 15000
> LSH_Band(df.r, 3 )
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 1 1 1 1 1 1 1
[2,] 1 1 0 0 0 0 0
[3,] 0 0 0 0 0 0 0
Die Punktfunktion ist das Skalarprodukt zweier Vektoren.
- Meine Lsh-Funktion nimmt eine Zeile meiner Daten und dann einen Teil der erhaltenen Zeile mit
df.r[j,][rd[,i]]
.df.r[j,]
ist j-éme Zeile der Daten. rd[,i]
: rd ist eine K * K-Matrix von ganzen Zahlen zwischen 1 und ncol (df.r). Jede Spalte der Matrix enthält nur eindeutige ganze Zahlen.rn[,i]
: rn ist eine K * K-Matrix, die Werte des N (0,1) -Gesetzes enthält.In der resultierenden Tabelle werden Beobachtungen in Spalten dargestellt. Ich werde k Zeilen haben. Für die letzte Zeile werde ich das Skalarprodukt zwischen
df.r[j,][rd[,K]]
und berechnenrn[,K]
. Ich werde 1 erhalten, wenn das Skalarprodukt positiv ist.rd[,K]
undrn[,K]
wird nur für die letzte Zeile in der resultierenden Tabelle und für alle Beobachtungen in dieser Zeile verwendet.
Meine Frage :
Soll die Schleife durch die Variablen i und j durch eine Lapply-Funktion ersetzt werden ?
Meine realen Daten werden groß sein, deshalb stelle ich diese Frage.
Vielen Dank !
Das Folgende ist als Kommentar etwas zu lang, daher hier einige Hinweise / Probleme / Bemerkungen:
Zunächst muss ich sagen, dass ich Schwierigkeiten habe zu verstehen, was
LHS_Band
tut. Vielleicht würde hier ein Kontext helfen.Ich verstehe den Zweck bestimmter Funktionen nicht,
helpRFunctions::list.df.var.type
die einfach die Spaltennamen vondata
in a zurückzugeben scheinenlist
. Beachten Sie auch, dass diet$Intervals
RückgabeNULL
auf den von Ihnen angegebenen Beispieldaten basiert. Ich bin mir also nicht sicher, was dort los ist.Ich sehe den Funktionspunkt auch
pracma::dot
nicht. Das Punktprodukt zwischen zwei Vektoren kann in Basis R unter Verwendung von berechnet werden%*%
. Es ist wirklich kein zusätzliches Paket erforderlich.Funktion
hash
kann kompakter geschrieben werden alshash <- function(v, p) +(as.numeric(v %*% p) > 0)
Dies vermeidet die
if
Bedingung, die langsam ist.
Ungeachtet meines Unverständnisses, was Sie versuchen zu tun, sind hier einige Verbesserungen an Ihrem Code
hash <- function(v, p) +(as.numeric(v %*% p) > 0)
LSH_Band <- function(data, K, seed = NULL) {
# We retrieve numerical columns of data
data <- as.matrix(data[sapply(data, is.numeric)])
# we create K*K matrice using normal law
if (!is.null(seed)) set.seed(seed)
rn <- matrix(rnorm(K * K, 0, 1), nrow = K, ncol = K)
# we create K*K matrice of integers using uniform law , integrs are unique in each column
rd <- sapply(seq_len(K), function(col) sample.int(ncol(data), K))
buckets <- matrix(NA, nrow = K, ncol = nrow(data))
for (i in 1:K) {
buckets[i, ] <- apply(data, 1, function(row) hash(row[rd[, i]], rn[, i]))
}
buckets
}
- Fügen Sie immer eine Option hinzu, um ein Reproduzierbares zu verwenden,
seed
wenn Sie mit Zufallszahlen arbeiten. Das macht das Debuggen viel einfacher. - Sie können mindestens eine
for
Schleife durch ersetzenapply
(die bei VerwendungMARGIN = 1
durch die Zeilen einesmatrix
(oderarray
) iteriert ). - Ich habe alle unnötigen Paketabhängigkeiten entfernt und die Funktionalität durch Basis-R-Funktionen ersetzt.