Si può utilizzare la funzione lapply () per modificare il valore di ingresso?

StackOverflow https://stackoverflow.com/questions/1559724

  •  21-09-2019
  •  | 
  •  

Domanda

Mi chiedevo se è possibile utilizzare la funzione lapply () per modificare il valore dell'ingresso, simile a:

a1<-runif(100)
a2<-function(i){
a1[i]<-a1[i-1]*a1[i];a1[i]
}
a3<-lapply(2:100,a2)

Sto cercando qualcosa di simile a un for () loop, ma utilizzando l'infrastruttura lapply (). Non sono stato in grado di ottenere rapply () per fare questo.

Il motivo è che il "vero" a2 funzione è una funzione difficile che deve soltanto essere valutato se il valore di A1 [i-1] soddisfa alcuni criteri.

ri-fraseggio: così sto cercando di sostituire il for () nel seguente codice da un lapply () - cosa tipo:

    a1<-runif(100)
    a2<-function(i, a1){
        a1[i]<-a1[i-1]*2
        a1[i]
    }
    a3<-as.numeric(lapply(2:100, a2, a1=a1))
#compare the output of a3 with that of a1 after the recursive loop
    a2<-a1 #saved for comparison
    for(i in 2:length(a1)){
        a1[i]<-a1[i-1]*2
    }
cbind(a1[2:100],a3)
#actually this is would be like writting a lapply() version of the cumprod() function
cbind(a1,cumprod(a2))

La mailing list R ha consigliato alla ricerca fino alla funzione di Riduzione () .... come in:

a1<-runif(100)
cadd<-function(x) Reduce("*", x, accumulate = TRUE)
cadd(a1)

che dà lo stesso risultato di cumprod (a1) ... ma è anche più lento del ciclo:

a1<-runif(100000)
cadd<-function(x) Reduce("*", x, accumulate = TRUE)
looop<-function(a1){
j<-length(a1)
    for(i in 2:j){
        a1[i]<-a1[i-1]*a1[i]
    }
a1
}

> system.time(cadd(a1))
   user  system elapsed 
  1.344   0.004   1.353 
> system.time(cumprod(a1))
   user  system elapsed 
  0.004   0.000   0.002 
> system.time(loop(a1))
   user  system elapsed 
  0.772   0.000   0.775 
> 

Qualche idea?

È stato utile?

Soluzione

Modifica: In seguito alla vostra precisazione: no, non credo che è possibile utilizzare una funzione di applicarsi a fare qualcosa di simile in modo ricorsivo. Il punto di una funzione di applicazione è che essa si applica in tutto il vettore / matrice allo stesso tempo.

Si consiglia inoltre di un'occhiata a questa domanda relativa su StackOverflow .

La mia vecchia risposta:

Prova questo:

a1<-runif(100)
a2<-function(i, a1){
    a1[i]<-a1[i-1]*a1[i]
    a1[i]
}
a3 <- as.numeric(lapply(2:100, a2, a1=a1))

A differenza di un ciclo for, è necessario passare a un riferimento a tutto ciò che è necessario all'interno di un lapply. Il ritorno è anche una lista, quindi è necessario lanciare di nuovo in qualsiasi forma che si desidera.

Si potrebbe anche voler guardare il pacchetto plyr di modi semplici di fare questo genere di cose.

Al di là di questo, si può fare l'operazione senza un ciclo:

a3 <- a1[-length(a1)] * a1[-1]

In altre parole, queste affermazioni sono del tutto equivalenti:

> all((a1[-length(a1)] * a1[-1]) == as.numeric(lapply(2:100, a2, a1=a1)))
[1] TRUE

Ma la prima versione è preferibile in quanto non ha iterazioni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top