使用apply()函数跨子列表工作

时间:2014-08-31 20:02:54

标签: r apply boot nested-lists

我正在尝试7个人的饮食项目比例发生的自助计算并计算sd()

让我们说菜单上有9个猎物。

Diet <- c("Beaver","Bird", "Bobcat","Coyote", "Deer", "Elk",
    "Porcupine", "Raccoon",   "SmMamm")

这些猎物被同一物种的7个不同个体吃掉

Inds <- c("P01", "P02", "P03", "P04", "P05", "P06", "P07")

我的目标是每个人每个饮食项目按比例出现的自助 下面的循环为每个个体(每个包含N = 20个饲料的饮食)产生五个饮食,用替换取样。数据存储为个体列表,每个个体都包含样本饮食列表。

BootIndDiet <- list()
IndTotboot <- list()
for(i in Inds){
    for(j in 1:5){
        BootIndDiet[[j]] <- prop.table(table(sample(Diet, 20 ,replace = T)))
                        }
            IndTotboot[[i]] <- BootIndDiet
            }

下面我将个体P07的前两个饮食作为循环结果的一个例子

$P07
$P07[[1]]

   Beaver      Bird    Bobcat      Deer       Elk 
     0.05      0.15      0.20      0.10      0.15 
Porcupine   Raccoon    SmMamm 
     0.15      0.15      0.05 

$P07[[2]]

   Beaver      Bird    Bobcat    Coyote      Deer 
     0.15      0.10      0.20      0.05      0.05 
      Elk Porcupine   Raccoon    SmMamm 
     0.05      0.20      0.10      0.10 
然后,我想计算每个个体每个物种比例的sd()。同样地,对于每个人(P01 - P07),我想要在5个饮食中每个猎物物种按比例出现的sd()

当我上面的循环运行时,我怀疑有更好的方法(可能使用boot()函数)避免列表......

虽然我在这里只为每个人提供了5个样本(bootstraps),但我希望生成10000个。

非常感谢有关不同策略或如何在子列表中应用sd()的建议。

2 个答案:

答案 0 :(得分:2)

我试图以这种方式获取数组(而不是嵌套列表):

   IndTotboot <-array(replicate(5*length(Inds),prop.table(table(sample(as.factor(Diet), 20 ,replace = T))),simplify=T), dim=c(length(Diet),5,length(Inds)), dimnames=list(Diet,NULL,Inds))

使用replicate,您可以执行给定次数的表达式,并将结果存储为数组(如果可能)。我在as.factor之前添加了一个Diet,以确保该表能够跟踪每个饮食(即使是频率为0的饮食)。

获得的IndTotboot对象是一个三维数组,其中第一个索引表示Diet,第二个索引表示引导复制,第三个索引表示Inds。从那里,您可以以标准方式使用apply

编辑:

如果你尝试str(IndTotboot),你会得到:

    > str(IndTotboot)
     num [1:9, 1:5, 1:7] 0.1 0.15 0.15 0.1 0.1 0.1 0.15 0.05 0.1 0.15 ...
     - attr(*, "dimnames")=List of 3
       ..$ : chr [1:9] "Beaver" "Bird" "Bobcat" "Coyote" ...
       ..$ : NULL
       ..$ : chr [1:7] "P01" "P02" "P03" "P04" ...

第一行是最重要的。它说num [1:9, 1:5, 1:7],这意味着一个9x5x7阵列。其余表示dimnames,维度的名称,这是一个列表。它们是矩阵的rownamescolnames的推广。

现在,为了获得每个sdDiet的{​​{1}},您只需使用Inds

apply

答案 1 :(得分:0)

以下可能有用:

dd = data.frame(sapply(IndTotboot, function(x)x))

maindf = data.frame(Var1=as.character(), Freq=as.numeric())

for(rr in 1:nrow(dd)) for (cc in 1:ncol(dd)){
        maindf= merge(maindf, data.frame(dd[rr,cc]), all=TRUE)
}

> head(maindf, 10)
     Var1 Freq
1  Beaver 0.05
2  Beaver 0.10
3  Beaver 0.15
4  Beaver 0.20
5  Beaver 0.30
6    Bird 0.05
7    Bird 0.10
8    Bird 0.15
9    Bird 0.20
10   Bird 0.25


with(maindf, tapply(Freq, Var1, sd))
    Beaver       Bird     Bobcat     Coyote        Elk  Porcupine    Raccoon     SmMamm       Deer 
0.09617692 0.09354143 0.09354143 0.09354143 0.09354143 0.06454972 0.07905694 0.10801234 0.07905694 

对于每个人:

counter=1
for (cc in 1:ncol(dd)){
    maindf = data.frame(Var1=as.character(), Freq=as.numeric())
    for(rr in 1:nrow(dd)){
        maindf= merge(maindf, data.frame(dd[rr,cc]), all=TRUE)
    }
    cat("\nFor individual number: ",counter,"\n"); counter=counter+1
    print(with(maindf, tapply(Freq, Var1, sd)))
}


For individual number:  1 
    Beaver       Bird     Bobcat     Coyote        Elk  Porcupine    Raccoon     SmMamm       Deer 
0.05000000 0.07637626 0.05000000 0.06454972 0.03535534 0.05000000 0.05000000 0.07637626 0.05000000 

For individual number:  2 
    Beaver       Bird     Bobcat     Coyote       Deer        Elk  Porcupine    Raccoon     SmMamm 
0.05000000 0.10801234 0.03535534 0.05000000 0.09128709         NA 0.03535534 0.07637626 0.13149778 

For individual number:  3 
    Beaver       Bird     Bobcat     Coyote       Deer        Elk  Porcupine    Raccoon     SmMamm 
0.03535534 0.07637626 0.12583057 0.03535534 0.03535534 0.06454972 0.05000000 0.10606602 0.06454972 

For individual number:  4 
    Beaver       Bird     Bobcat     Coyote       Deer        Elk  Porcupine    Raccoon     SmMamm 
0.05000000 0.05000000 0.05000000 0.03535534 0.10408330 0.07905694 0.05000000 0.03535534 0.10408330 

For individual number:  5 
    Beaver       Bird     Bobcat     Coyote       Deer        Elk  Porcupine    Raccoon     SmMamm 
0.05000000 0.03535534 0.05000000 0.03535534 0.03535534 0.03535534 0.05000000 0.05000000 0.07071068 

For individual number:  6 
    Beaver     Coyote       Deer        Elk  Porcupine    Raccoon     SmMamm     Bobcat       Bird 
0.10000000 0.07637626 0.03535534 0.05000000 0.07071068 0.03535534 0.05000000 0.10408330 0.10606602 

For individual number:  7 
    Beaver       Bird     Bobcat     Coyote       Deer        Elk  Porcupine    Raccoon     SmMamm 
0.03535534 0.05000000 0.10408330 0.07637626 0.05000000 0.13228757 0.07637626 0.03535534 0.05000000 

对于个人+物种:

maindf = data.frame(Var1=as.character(), Freq=as.numeric(), ind=as.numeric())
counter=1
for (cc in 1:ncol(dd)){
    for(rr in 1:nrow(dd)){
        maindf= merge(maindf, cbind(data.frame(dd[rr,cc]),ind=counter), all=TRUE)
    }
    counter=counter+1
}
with(maindf, tapply(Freq, list(Var1,ind), sd))

                   1          2          3          4          5          6          7
Beaver    0.05000000 0.05000000 0.03535534 0.05000000 0.05000000 0.10000000 0.03535534
Bird      0.07637626 0.10801234 0.07637626 0.05000000 0.03535534 0.10606602 0.05000000
Bobcat    0.05000000 0.03535534 0.12583057 0.05000000 0.05000000 0.10408330 0.10408330
Coyote    0.06454972 0.05000000 0.03535534 0.03535534 0.03535534 0.07637626 0.07637626
Elk       0.03535534         NA 0.06454972 0.07905694 0.03535534 0.05000000 0.13228757
Porcupine 0.05000000 0.03535534 0.05000000 0.05000000 0.05000000 0.07071068 0.07637626
Raccoon   0.05000000 0.07637626 0.10606602 0.03535534 0.05000000 0.03535534 0.03535534
SmMamm    0.07637626 0.13149778 0.06454972 0.10408330 0.07071068 0.05000000 0.05000000
Deer      0.05000000 0.09128709 0.03535534 0.10408330 0.03535534 0.03535534 0.05000000