0

次のように定義された関数があります。

foo<-function(data){
    for (i in 2:10)
    run.model<-mark(data[sample(nrow(data), i),], model="Occupancy")
    results<-data.frame(mean(summary(run.model)$real$p), summary(run.model)$real$Psi, i)
    return(results)
    }

「マーク」は、興味のあるモデルを実行するための関数です。ただし、結果には i=10 の最後のモデルのみが含まれます

  mean.summary.run.model..real.p.        X1  i
1                       0.1403083 0.6414447 10

i=2 から i=10 に結果をコンパイルするように関数を修正するにはどうすればよいですか?


(自分の質問に答えられないので、コードをどのように変更したかを示すために質問を編集しました:

あなたがた両方に感謝します。

@David Robinson のコードを修正しました

foo<-function(data){
    do.call(rbind, lapply(2:6, function(i){
        run.model<-mark(data[sample(nrow(data), i),], model="Occupancy")
        cbind(p=mean(summary(run.model)$real$p), Psi=summary(run.model)$real$Psi, stations=i)
        }))
    }

そして、これらの出力を得ました:

         p            1 stations
 0.4895234 1.388066e-10        2
 0.2902716 3.445050e-01        3
 0.0942734 7.955582e-01        4
 0.1683427 2.376106e-01        5
 0.1683427 1.980088e-01        6

なぜ 2 番目の列に名前を付けたのに、出力に表示されなかったのだろうか?

@zzk のコードについては、以下のように変更しました。

foo<-function(data){
results.frame <- data.frame()
for (i in 2:6) {
    run.model<-mark(data[sample(nrow(data), i),], model="Occupancy")
    results<-data.frame(p=mean(summary(run.model)$real$p), Psi=summary(run.model)$real$Psi, stations=i)          
    results.frame <- rbind(results.frame, results)
    }
return(results.frame)
}

そして出力:

          p           X1 stations
1 0.1683427 5.940264e-01        2
2 0.5533567 7.292506e-12        3
3 0.0500000 1.000000e+00        4
4 0.1683427 7.128317e-01        5
5 0.2321999 3.588861e-01        6

ほとんど同じです。

その他の質問は次のとおりです。 1. このループを n 回繰り返したい場合は、関数「複製」を使用したいと思います。しかし、私はそれを置く方法がわかりません。2. 後で操作できるように、出力を data.frame として作成することは可能ですか? (例: 平均の計算、グラフの作成、グループ化など)


私は複製(10、foo(データ))を使用しました

これが私が得たものです。出力が問題になり、行と列が反転しているように見えます。"replicate(100, foo(data), simple="data.frame")" と同じ結果になります。

         [,1]      [,2]      [,3]      [,4]      [,5]      [,6]      [,7]      [,8]      [,9]      [,10]    
p        Numeric,3 Numeric,3 Numeric,3 Numeric,3 Numeric,3 Numeric,3 Numeric,3 Numeric,3 Numeric,3 Numeric,3
X1       Numeric,3 Numeric,3 Numeric,3 Numeric,3 Numeric,3 Numeric,3 Numeric,3 Numeric,3 Numeric,3 Numeric,3
se.p     Numeric,3 Numeric,3 Numeric,3 Numeric,3 Numeric,3 Numeric,3 Numeric,3 Numeric,3 Numeric,3 Numeric,3
se.Psi   Numeric,3 Numeric,3 Numeric,3 Numeric,3 Numeric,3 Numeric,3 Numeric,3 Numeric,3 Numeric,3 Numeric,3
stations Integer,3 Integer,3 Integer,3 Integer,3 Integer,3 Integer,3 Integer,3 Integer,3 Integer,3 Integer,3

しかし、このコードを使用すると (出力にもう 1 列あります)

foo<-function(data){
do.call(rbind, lapply(2:4, function(i){
    run.model<-mark(data[sample(nrow(data), i),], model="Occupancy")
    cbind(mean(summary(run.model)$real$p), Psi=summary(run.model)$real$Psi, se.p=mean(summary(run.model, se=T)$real$p$se), stations=i)
    }))
}

replicate(5, foo(data))

私は得た

, , 1

                  1      se.p stations
 0.4895234 1.388066e-10 0.0000000        2
 0.0333333 1.000000e+00 0.0327731        3
 0.2117159 8.265795e-01 0.0833965        4

, , 2
.....
.....
, , 5

                   1      se.p stations
 0.2902716 0.5167575 0.1519857        2
 0.2000000 1.0000000 0.0730297        3
 0.2902716 0.2583787 0.1519857        4

replica(5, foo(data), simple="data.frame") を使用

私はこれらを手に入れました。

             [,1]         [,2]         [,3]         [,4]      [,5]
 [1,] 4.895234e-01 1.683427e-01 4.895234e-01 1.683427e-01 0.1683427
 [2,] 1.683427e-01 5.533567e-01 2.902716e-01 5.533567e-01 0.0666667
 [3,] 2.500000e-02 2.117159e-01 2.321999e-01 3.974777e-01 0.0250000
 [4,] 1.388066e-10 5.940264e-01 1.388066e-10 5.940264e-01 0.5940264
 [5,] 3.960176e-01 7.292506e-12 3.445050e-01 7.292506e-12 1.0000000
 [6,] 1.000000e+00 8.265795e-01 5.383291e-01 2.515864e-01 1.0000000
 [7,] 0.000000e+00 1.379382e-01 0.000000e+00 1.379382e-01 0.1379382
 [8,] 1.379382e-01 0.000000e+00 1.519857e-01 0.000000e+00 0.0455420
 [9,] 2.468550e-02 8.339650e-02 1.038181e-01 1.575997e-01 0.0246855
[10,] 2.000000e+00 2.000000e+00 2.000000e+00 2.000000e+00 2.0000000
[11,] 3.000000e+00 3.000000e+00 3.000000e+00 3.000000e+00 3.0000000
[12,] 4.000000e+00 4.000000e+00 4.000000e+00 4.000000e+00 4.0000000

私が必要とするのは、それぞれについて3回繰り返す場合です:

          p           X1 stations
1 0.1683427 5.940264e-01        2
2 0.4687956 0.9876516334        2
3 xxxxxxxx  xxxxxxxxxxxx        2
4 xxxxxxxxx xxxxxxxxxxxx        3
5 0.5533567 7.292506e-12        3
6 xxxxxxxxx xxxxxxxxxxxx        3
.................................
13 0.0500000 1.000000e+00       6
14 0.1683427 7.128317e-01       6
15 0.2321999 3.588861e-01       6
4

2 に答える 2

5

You cannot return a value multiple times- only the first return statement will occur, and the rest of the function will never run. Furthermore, you don't have brackets after your for loop, so the only line that is included in the for loop is:

for (i in 2:10)
    run.model<-mark(data[sample(nrow(data), i),], model="Occupancy")

This line thus runs 9 times, setting run.model to something different each time. Then the line:

results<-data.frame(mean(summary(run.model)$real$p), summary(run.model)$real$Psi, i)
return(results)

occurs only once. If you instead want to return a list with separate 9 data frames in it, you would do something more like:

foo<-function(data){
    lapply(2:10, function(i) {
        run.model<-mark(data[sample(nrow(data), i),], model="Occupancy")
        data.frame(mean(summary(run.model)$real$p), summary(run.model)$real$Psi)
    }
}

You could also combine that list into a single data frame (depending on how you want the data combined and returned). You could do that with do.call and cbind, though there are other solutions:

foo<-function(data){
    do.call(cbind, lapply(2:10, function(i) {
        run.model<-mark(data[sample(nrow(data), i),], model="Occupancy")
        cbind(mean(summary(run.model)$real$p), summary(run.model)$real$Psi)
    })
}
于 2012-08-29T16:08:24.283 に答える
3

David Robinson の説明は完全に正しいですが、lapply 関数ではなく明示的な for ループを維持したい場合は、これでうまくいくはずです。

foo<-function(data){
    results.frame <- data.frame()
    for (i in 2:10) {
        run.model<-mark(data[sample(nrow(data), i),], model="Occupancy")
        results<-data.frame(mean(summary(run.model)$real$p), summary(run.model)$real$Psi, i)          
        results.frame <- rbind(results.frame, results)
    }
    return(results.frame)
}

レプリケートに関する 2 番目の質問に答えるには、次のようにします。関数を 100 回レプリケートするとします。次のコードは、各 data.frame を長さ 100 のリストに入れます。

replicate(100, foo(data))

結果をデータフレームで取得したい場合:

replicate(100, foo(data), simplify="data.frame")

ただし、行/列が保持されるかどうかはよくわかりません。

于 2012-08-29T16:24:18.203 に答える