列表中嵌套列表的元素平均值

5
我有一个列表的列表,其中每个列表都包含股票名称和它们的值。这些股票对于每个列表都是相同的,但其值不同。现在,我想看到每个股票的平均值。问题是我不知道如何指定查找每个列表中特定股票并提取其价值。例如,我想要在这三个列表中得到"jpm"的平均值。它将为mean(c(0.08620690,0.10000000,0.10000000))= 0.095402。我该怎么做?
我的解决方案:
dput(degree.l)
list(c(schwab = 0, pnc = 0.0344827586206897, jpm = 0.0862068965517241, 
amex = 0.0862068965517241, gs = 0.103448275862069, ms = 0.103448275862069, 
bofa = 0.103448275862069, citi = 0.103448275862069, wf = 0.120689655172414, 
spgl = 0.120689655172414, brk = 0.137931034482759), c(schwab = 0.0166666666666667, 
pnc = 0.05, ms = 0.0666666666666667, spgl = 0.0833333333333333, 
jpm = 0.1, bofa = 0.1, wf = 0.1, amex = 0.1, gs = 0.116666666666667, 
brk = 0.116666666666667, citi = 0.15), c(schwab = 0.0428571428571429, 
gs = 0.0714285714285714, pnc = 0.0714285714285714, citi = 0.0857142857142857, 
amex = 0.0857142857142857, spgl = 0.0857142857142857, jpm = 0.1, 
brk = 0.1, ms = 0.114285714285714, wf = 0.114285714285714, bofa = 0.128571428571429
))

degree.unl <- unlist(degree.l)
4个回答

4

unlist之前,

apply(do.call(rbind, degree.l), 2, mean)
#     schwab        pnc        jpm       amex         gs         ms       bofa 
# 0.01984127 0.05197044 0.07476738 0.08508484 0.09638752 0.09638752 0.10114943 
#       citi         wf       spgl        brk 
# 0.10114943 0.11721401 0.11721401 0.13883415 

编辑:既然你说不能假设股票代码是按顺序排列的,那我们可以解决这个问题:

nms <- unique(unlist(lapply(degree.l, names)))
nms
#  [1] "schwab" "pnc"    "jpm"    "amex"   "gs"     "ms"     "bofa"   "citi"  
#  [9] "wf"     "spgl"   "brk"   

apply(do.call(rbind, lapply(degree.l, `[`, nms)), 2, mean)
#     schwab        pnc        jpm       amex         gs         ms       bofa 
# 0.01984127 0.05197044 0.09540230 0.09064039 0.09718117 0.09480022 0.11067323 
#       citi         wf       spgl        brk 
# 0.11305419 0.11165846 0.09657909 0.11819923 

为了好玩,我们可以将它们混合以确认这个功能是否有效:

set.seed(42)
degree.l.jumbled <- lapply(degree.l, sample)
degree.l.jumbled
# [[1]]
#     schwab         gs        brk         wf        pnc       amex       bofa 
# 0.00000000 0.10344828 0.13793103 0.12068966 0.03448276 0.08620690 0.10344828 
#       spgl       citi         ms        jpm 
# 0.12068966 0.10344828 0.10344828 0.08620690 
# [[2]]
#       amex         wf       spgl     schwab        jpm       bofa         gs 
# 0.10000000 0.10000000 0.08333333 0.01666667 0.10000000 0.10000000 0.11666667 
#        pnc        brk       citi         ms 
# 0.05000000 0.11666667 0.15000000 0.06666667 
# [[3]]
#         ms       bofa       citi       amex        jpm        brk       spgl 
# 0.11428571 0.12857143 0.08571429 0.08571429 0.10000000 0.10000000 0.08571429 
#         wf         gs        pnc     schwab 
# 0.11428571 0.07142857 0.07142857 0.04285714 
apply(do.call(rbind, lapply(degree.l.jumbled, `[`, nms)), 2, mean)
#     schwab        pnc        jpm       amex         gs         ms       bofa 
# 0.01984127 0.05197044 0.09540230 0.09064039 0.09718117 0.09480022 0.11067323 
#       citi         wf       spgl        brk 
# 0.11305419 0.11165846 0.09657909 0.11819923 

所以这不正确,因为例如“jpm”股票代码并不总是在同一个位置。但我可以将它们放在相同的顺序中,这样就可以工作了。谢谢! - statwoman
已修正,见我的编辑。为了公平起见,你在这里的评论与你在问题中陈述的“这些股票代码对于每个列表都是相同的”相反。它们要么不变,要么改变,你需要在问题中明确,提供样本数据,并在评估结果时保持一致。 - r2evans

4

另一种选择:

get_ticker <- function(t) mean(sapply(d, "[[", t))
sapply(names(degree.l[[1]]), get_ticker)

3
我们可以在base R中使用aggregatestack
aggregate(values ~ ind, do.call(rbind, lapply(degree.l, stack)), FUN = mean)

-输出

  ind     values
1  schwab 0.01984127
2     pnc 0.05197044
3     jpm 0.09540230
4    amex 0.09064039
5      gs 0.09718117
6      ms 0.09480022
7    bofa 0.11067323
8    citi 0.11305419
9      wf 0.11165846
10   spgl 0.09657909
11    brk 0.11819923

另一个选项是使用Reduce函数(假设没有缺失值),进行逐元素加法(+),然后除以list的长度。

 Reduce(`+`, degree.l)/length(degree.l)
    schwab        pnc        jpm       amex         gs         ms       bofa       citi         wf       spgl        brk 
0.01984127 0.05197044 0.07476738 0.08508484 0.09638752 0.09638752 0.10114943 0.10114943 0.11721401 0.11721401 0.13883415 

或者,如果OP已经将数据集unlist,则可以使用该对象按names进行分组,并使用tapply函数。
tapply(degree.unl, names(degree.unl), FUN = mean)
      amex       bofa        brk       citi         gs        jpm         ms        pnc     schwab       spgl         wf 
0.09064039 0.11067323 0.11819923 0.11305419 0.09718117 0.09540230 0.09480022 0.05197044 0.01984127 0.09657909 0.11165846 

第一个和最后一个可行,而最后一个实际上非常好!然而第二个与其他人的价值不同。这是因为股票的位置不固定。谢谢! - statwoman
@statwoman 第二种解决方案有两个前提条件需要满足:1)没有缺失(NA)值,2)每个元素的长度相同且顺序相同。 - akrun

0

使用rbindlist+colMeans选项的data.table

> colMeans(rbindlist(Map(function(x) data.frame(t(x)), degree.1), use.names = TRUE))
    schwab        pnc        jpm       amex         gs         ms       bofa
0.01984127 0.05197044 0.09540230 0.09064039 0.09718117 0.09480022 0.11067323
      citi         wf       spgl        brk
0.11305419 0.11165846 0.09657909 0.11819923

接下来,如果你想通过任何名称(例如schwab)检索平均值,你可以尝试以下方法:

colMeans(rbindlist(Map(function(x) data.frame(t(x)), degree.1), use.names = TRUE))["schwab"]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接