我的函数定义为:
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,以便我以后可以操作它? (例如计算方法,制作图表,分组......等)
这是我得到的。看起来输出变得有问题并且行和列被反转。与“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
答案 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.call
和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)
})
}
答案 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")
不太确定是否会保留行/列。