Entgegen der landläufigen Meinung, ist sapply
nicht unbedingt schneller als ein for
Schleife
testen wir ein paar verschiedene Methoden mit microbenchmark
library(microbenchmark)
u<-1:10
k<-3
Ich erfinde hier eine Funktion zum Zwecke der Prüfung:
leg<-function(u,k){u**(1:k)}
Lassen Sie uns verschiedene Methoden testen:
method1<-function(u,k){
l = leg(u[1],k)
for (i in 2:length(u)){l=rbind(l,leg(u[i],k))}
}
method2<-function(u,k){
l<-matrix(nrow = length(u),ncol = k)
for (i in 1:length(u)){l[i,]<-leg(u[i],k)}
}
method3<-function(u,k){
l <- do.call(rbind,lapply(1:length(u),function(i)leg(u[i],k)))
}
Jetzt:
microbenchmark(times = 100, method1(u,k),method2(u,k),method3(u,k))
expr min lq mean median uq max neval
method1(u, k) 30.031 32.6920 36.88837 34.2125 41.4350 53.219 100
method2(u, k) 21.668 25.8490 29.60131 27.1800 32.6915 70.705 100
method3(u, k) 21.667 26.2295 29.42637 27.3700 33.0715 51.699 100
Wenn wir vektorisieren unsere Funktion:
leg2<-function(u,k){
result<-matrix(nrow = length(u),ncol = k);
for(i in 1:k){result[,i]<-u**i}
}
microbenchmark(times = 100, method1(u,k),method2(u,k),method3(u,k),leg2(u,k))
Unit: microseconds
expr min lq mean median uq max neval
method1(u, k) 28.891 31.1710 34.79391 32.692 37.8235 64.243 100
method2(u, k) 20.527 24.7085 29.20205 26.229 31.3610 79.068 100
method3(u, k) 22.428 24.7090 28.49507 26.610 31.1710 71.465 100
leg2(u, k) 6.462 7.6030 9.03213 8.363 8.7430 19.768 100
So etwa 3-mal schneller!
Vielleicht kann dies effizienter sein: 'l <- do.call (rbind, lapply (1: Länge (u), Funktion (i) Bein (u [i], k)))', sollten Sie dennoch überlegen um deine 'Bein'-Funktion mehr vektorisiert zu machen (wenn möglich), dh, du kannst'U' statt'U [i] annehmen' – digEmAll
Die Vorbelegung der Matrix kann auch verbessern: 'l <-Matrix (nrow = Länge (u), k) ' ' für (i in 1: Länge (u)) {l = l [i,] (l, Bein (u [i], k))} – DeveauP