【问题标题】:Working across sub-lists with apply() functions使用 apply() 函数跨子列表工作
【发布时间】:2014-08-31 20:02:54
【问题描述】:

我正在尝试引导 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 个样本(引导程序),但我希望生成 10000 个。

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

【问题讨论】:

  • 除非出现内存问题,否则您可以将数据存储在长格式“data.frame”中,其中包含-say- [ind, No_diet, prey, prop] 列,然后您可以调用aggregate(prop ~ ind + prey, mydataframe, sd)

标签: r apply nested-lists statistics-bootstrap


【解决方案1】:

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

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

获得的IndTotboot 对象是一个3 维数组,其中第一个索引表示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 的推广。

现在,要为每个DietInds 获取sd,您只需使用apply

    apply(IndTotboot,MARGIN=c(1,3),sd)

【讨论】:

  • 很酷的想法@nicola,虽然我无法获得 apply() 的代码。 IndTotboot 对象的 str() 表示列表,但 lapply(IndTotboot, sd) 的结果显然不正确。我错过了什么……?
  • IndTotboot 是一个数组,而不是一个列表。我将扩展我的答案以展示如何使用 apply。
【解决方案2】:

以下可能有用:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-16
    • 1970-01-01
    • 2020-08-19
    • 2020-01-29
    相关资源
    最近更新 更多