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

“mark”是运行我感兴趣的模型的功能。但是,结果仅包含 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

我想知道为什么我命名了第二列但它没有出现在输出中?

对于@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 次,我想使用函数“replicate”。但我不知道该怎么说。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

使用复制(5,foo(数据),简化=“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

您不能多次返回一个值 - 只有第一个 return 语句会发生,而函数的其余部分将永远不会运行。此外,您的 for 循环后没有括号,因此 for 循环中包含的唯一行是:

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

因此,这条线运行了 9 次,run.model每次都设置为不同的值。然后是一行:

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

只发生一次。如果您想返回一个包含单独 9 个数据框的列表,您可以执行以下操作:

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

您还可以将该列表组合成一个数据框(取决于您希望如何组合和返回数据)。您可以使用do.calland来做到这一点cbind,尽管还有其他解决方案:

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

大卫罗宾逊的解释是完全正确的,但如果你想保持明确的 for 循环而不是 lapply 函数,这应该工作:

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

要回答关于复制的第二个问题:以下应该有效,假设您想复制函数 100 次,以下代码会将每个 data.frame 放入长度为 100 的列表中:

replicate(100, foo(data))

如果您想要数据框中的结果:

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

不太确定行/列是否会被保留。

于 2012-08-29T16:24:18.203 回答