使用 apply() 函数跨子列表工作 [英] Working across sub-lists with apply() functions
问题描述
我正在尝试引导 7 个人饮食项目的发生比例并计算 sd()
I am trying to the bootstrap the proportional occurrence of diet items for 7 individuals and calculate a sd()
假设菜单上有 9 个猎物.
Lets say there are 9 prey items on the menu.
Diet <- c("Beaver","Bird", "Bobcat","Coyote", "Deer", "Elk",
"Porcupine", "Raccoon", "SmMamm")
而且这些猎物被同一物种的 7 个不同个体吃掉
And that these prey items are eaten by 7 different individuals of the same species
Inds <- c("P01", "P02", "P03", "P04", "P05", "P06", "P07")
我的目标是引导每个人每个饮食项目的出现比例.
下面的循环为每个个体生成五种饮食(每种饮食包含 N = 20 次喂养),这些饮食被替换采样.数据存储为个体列表,每个个体包含一个样本饮食列表.
My goal is the bootstrap the proportional occurrence of each diet item for each individual.
The loop below generates five diets for each individual (each diet containing N = 20 feedings) that were sampled with replacement. The data are stored as a list of the individuals, each of which contains a list of the sample diets.
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 的前两种饮食作为循环结果的示例
Below I have included the first two diets of individual P07 as an example of the loop results
$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),我想要 sd()
在 5 种饮食中每个猎物物种的出现比例.
I then want to calculate the sd() of the proportional of each species for each individual. Equivocally, for each individual (P01 - P07) I want the sd()
of the proportional occurrence of each prey species across the 5 diets.
当我上面的循环运行时,我怀疑有更好的方法(可能使用 boot() 函数)来避免列表......
While my loop above runs, I suspect there is a better way (possibly using the boot() function) that avoids lists...
虽然我在这里只为每个人包含了 5 个样本(引导程序),但我希望生成 10000 个.
While I have only included 5 samples (bootstraps) for each individual here, I hope to generate 10000.
非常感谢有关不同策略或如何在子列表中应用 sd()
的建议.
Suggestions on a different strategy or how to apply sd()
across sub-lists is greatly appreciated.
推荐答案
我会尝试以这种方式获取数组(而不是嵌套列表):
I'd try to obtain an array (instead of a nested list) in this way:
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 的饮食).
With replicate
you can execute an expression a given number of times and store the result as an array (if possible). I added an as.factor
before Diet
to make sure that the table takes trace of every Diet (even the ones with a 0 frequency).
获得的IndTotboot
对象是一个3维数组,其中第一个索引表示Diet
,第二个索引表示引导复制,第三个索引表示Inds代码>.从那里您可以以标准方式使用
apply
.
The IndTotboot
object obtained is a 3-dimensional array where the first index indicates the Diet
, the second the bootstrap replications and the third the Inds
. From there you can use apply
in the standard way.
如果你尝试 str(IndTotboot)
你会得到:
If you try str(IndTotboot)
you get:
> 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
,维度的名称,是一个列表.它们是矩阵的 rownames
和 colnames
的概括.
The first line is the most important. It says num [1:9, 1:5, 1:7]
, which means a 9x5x7 array. The rest indicates the dimnames
, the names of the dimensions, which is a list. They are the generalization of the rownames
and the colnames
for a matrix.
现在,要获取每个 Diet
和 Inds
的 sd
,您只需使用 apply
:
Now, to obtain the sd
for every Diet
and Inds
you just use apply
:
apply(IndTotboot,MARGIN=c(1,3),sd)
这篇关于使用 apply() 函数跨子列表工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!