Parfois, nous devons utiliser des boucles, par exemple, lorsque nous ne savons pas combien d'itérations nous avons besoin pour obtenir le résultat. Prenons l'exemple des boucles while. Voici les méthodes que vous devez absolument éviter:
a=numeric(0)
b=1
system.time(
{
while(b<=1e5){
b=b+1
a<-c(a,pi)
}
}
)
# user system elapsed
# 13.2 0.0 13.2
a=numeric(0)
b=1
system.time(
{
while(b<=1e5){
b=b+1
a<-append(a,pi)
}
}
)
# user system elapsed
# 11.06 5.72 16.84
Celles-ci sont très inefficaces car R copie le vecteur à chaque ajout.
Le moyen le plus efficace d'ajouter est d'utiliser l'index. Notez que cette fois, je le laisse itérer 1e7 fois, mais c'est quand même beaucoup plus rapide que c
.
a=numeric(0)
system.time(
{
while(length(a)<1e7){
a[length(a)+1]=pi
}
}
)
# user system elapsed
# 5.71 0.39 6.12
C'est acceptable. Et nous pouvons le rendre un peu plus rapide en remplaçant [
par [[
.
a=numeric(0)
system.time(
{
while(length(a)<1e7){
a[[length(a)+1]]=pi
}
}
)
# user system elapsed
# 5.29 0.38 5.69
Peut-être avez-vous déjà remarqué que cela length
peut prendre du temps. Si nous remplaçons length
par un compteur:
a=numeric(0)
b=1
system.time(
{
while(b<=1e7){
a[[b]]=pi
b=b+1
}
}
)
# user system elapsed
# 3.35 0.41 3.76
Comme d'autres utilisateurs l'ont mentionné, la pré-allocation du vecteur est très utile. Mais c'est un compromis entre la vitesse et l'utilisation de la mémoire si vous ne savez pas combien de boucles vous avez besoin pour obtenir le résultat.
a=rep(NaN,2*1e7)
b=1
system.time(
{
while(b<=1e7){
a[[b]]=pi
b=b+1
}
a=a[!is.na(a)]
}
)
# user system elapsed
# 1.57 0.06 1.63
Une méthode intermédiaire consiste à ajouter progressivement des blocs de résultats.
a=numeric(0)
b=0
step_count=0
step=1e6
system.time(
{
repeat{
a_step=rep(NaN,step)
for(i in seq_len(step)){
b=b+1
a_step[[i]]=pi
if(b>=1e7){
a_step=a_step[1:i]
break
}
}
a[(step_count*step+1):b]=a_step
if(b>=1e7) break
step_count=step_count+1
}
}
)
#user system elapsed
#1.71 0.17 1.89
vector = values
; ou vous pouvez faire vector = vecteur + valeurs. Mais je ne comprends peut-être pas votre cas d'utilisation