For循环并申请在R中的嵌套列表上进行数学运算(从Bchron中找到校准年龄的平均值)

For loop and apply to do math on a nested list in R (finding mean of calibrated ages from Bchron)

首先,我是 R 和 Stack Overflow 的新手,所以我提前为不可避免的 失礼 或我在这个问题上犯的愚蠢错误道歉我能做什么来补救他们。同时,请原谅我的幼稚

我正在使用 R 程序包 Bchron 来校准放射性碳日期(即,将有误差的 14C 年龄转换为校准曲线的概率分布,尤其是产生点估计(例如,平均值) 对于那个概率分布)。 我的目标是获得同时校准多个日期所产生的加权平均年龄向量。在这种情况下,加权平均值是校准年龄网格与概率的乘积之和密度。

假设我们只校准三个日期,如下所示:

library(Bchron)

ages1 <- BchronCalibrate(ages=c(3445,11553,7456), 
                    ageSds=c(50,230,110),
                    calCurves=c('intcal13','intcal13','shcal13'),
                    ids=c('sample1','sample2','sample3'))

Bchron 输出校准(即来自 BchronCalibrate())作为向量列表。一次获得平均值很容易:

print (sum(ages1$'sample1'$ageGrid * ages1$'sample1'$densities))

但是当我们校准多个日期时,我们会得到一个日期列表(由 "ids" 以上),每个都包含该日期的校准列表。鉴于嵌套列表,我很难弄清楚如何从我的列表中获取向量中的多个均值。窥探 Stack Exchange,我发现了很多迭代列表的示例,甚至是嵌套应用函数的示例,但不幸的是,鉴于我相对缺乏经验,我似乎无法使它们适应我的问题。以下是我到目前为止所得到的。

鉴于 ageGriddensities 向量始终是父列表中每个日期的第 4 和第 5 个列表项,我认为它应该很简单......类似于

 for(sample.age in ages1) {
 sapply(ages1[[sample.age]],sum([4]*[5]))
 }

考虑到我在各种尝试中遇到的所有错误,很明显我的语法或者(更有可能)我对此的整个思路是混乱的。

即使我可以让基本的 for 循环工作,我如何要求它 return 一个向量?

感谢任何有关此主题的帮助,特别感谢那些简单到足以让像我这样的新手理解的答案。

干杯, 马特

R sapply 和 lapply 函数是伪装的循环。 (如果我理解这个问题,你只需要一个循环。)我正在避免你使用数字索引的努力,而是建议你坚持使用字符索引,因为它们不太容易被误解。

sapply(ages1, function(x) sum(x[['ageGrid']]*x[['densities']]))

#  sample1   sample2   sample3 
# 3713.214 13372.815  8217.632 

sapply 函数一次将那些带有不同标记的 sample 项传递给提取和相乘它们的函数。完成乘法后,它会返回计算它们的列表的名称。在 R 练习的开始阶段,查看您正在处理的对象的结构通常很有用:

str(ages1)
List of 3
 $ sample1:List of 5
  ..$ ages     : num 3445
  ..$ ageSds   : num 50
  ..$ calCurves: chr "intcal13"
  ..$ ageGrid  : num [1:473] 3470 3471 3472 3473 3474 ...
  ..$ densities: num [1:473] 1.01e-05 1.01e-05 1.01e-05 1.01e-05 1.01e-05 ...
 $ sample2:List of 5
  ..$ ages     : num 11553
  ..$ ageSds   : num 230
  ..$ calCurves: chr "intcal13"
  ..$ ageGrid  : num [1:1489] 12711 12712 12713 12714 12715 ...
  ..$ densities: num [1:1489] 1.05e-05 1.11e-05 1.17e-05 1.23e-05 1.30e-05 ...
 $ sample3:List of 5
  ..$ ages     : num 7456
  ..$ ageSds   : num 110
  ..$ calCurves: chr "shcal13"
  ..$ ageGrid  : num [1:714] 7860 7861 7862 7863 7864 ...
  ..$ densities: num [1:714] 1.00e-05 1.04e-05 1.08e-05 1.13e-05 1.17e-05 ...
 - attr(*, "class")= chr "BchronCalibratedDates"