返回所有输出的R函数不是最后一个

时间:2012-08-29 15:53:41

标签: r function dataframe

我的函数定义为:

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

几乎一样。

其他问题是: 如果我想在这个循环中重复一次,我想使用函数“replicate”。但我不知道怎么说。 2.是否可以将输出作为data.frame,以便我以后可以操作它? (例如计算方法,制作图表,分组......等)


我用过     复制(10,foo(数据))

这是我得到的。看起来输出变得有问题并且行和列被反转。与“replicate(100,foo(data),simplify =”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

但是如果我使用这段代码(在输出中再增加一列)

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

使用     replicate(5,foo(data),simplify =“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

2 个答案:

答案 0 :(得分: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.callcbind执行此操作,但还有其他解决方案:

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

答案 1 :(得分:3)

David Robinson的解释是完全正确的,但是如果你想保持显式的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")

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