2

次のように、 lapply() 関数を使用して入力の値を変更できるかどうか疑問に思っていました。

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

for() ループに似たものを探していますが、lapply() インフラストラクチャを使用しています。これを行うために rapply() を取得できませんでした。

その理由は、「実際の」a2 関数は、a1[i-1] の値がいくつかの基準を満たしている場合にのみ評価する必要がある難しい関数だからです。

言い直し: だから私は以下のコードの for() を lapply() タイプのものに置き換えようとしています:

    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))

R メーリング リストは、Reduce() 関数を検討することを勧めています....次のように:

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

cumprod(a1) と同じ結果が得られますが、ループよりもさらに遅くなります。

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 
> 

何か案が ?

4

1 に答える 1

2

編集:あなたの説明に従って:いいえ、apply関数を使用してそのような再帰的なことを行うことができるとは思いません。適用関数の要点は、ベクトル/行列全体に同時に適用されることです。

また、stackoverflowでこの関連する質問を確認することもできます。

私の古い答え:

これを試して:

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))

ループとは異なり、for内で必要なものへの参照を渡す必要がありますlapply。返品もリストなので、好きな形にキャストして戻す必要があります。

この種のことを簡単に行う方法については、plyrパッケージを確認することもできます。

それを超えて、ループなしで操作を行うことができます。

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

言い換えれば、これらのステートメントは完全に同等です。

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

ただし、最初のバージョンは反復がないため、推奨されます。

于 2009-10-13T13:25:22.427 に答える