列表列表中元素的平均值
Posted
技术标签:
【中文标题】列表列表中元素的平均值【英文标题】:Mean of an element in list of lists 【发布时间】:2021-09-30 01:30:33 【问题描述】:我有一个列表列表,其中每个列表都包含代码(名称)及其值。对于每个列表,这些代码保持不变,但值不同。现在,我想看看这些代码的平均值是多少。问题是我不知道如何指定查看每个列表中的特定代码并提取值。例如,我想要这 3 个列表中“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)
【问题讨论】:
【参考方案1】:我们可以在base R
中使用aggregate
和stack
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
(假设没有NA)进行元素加法(+
)并除以list
的length
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
ed 数据集,然后使用该对象,按 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 第二种解决方案有两个假设要满足 1) 没有缺失 (NA
) 值,2) 每个元素的长度相同且顺序相同【参考方案2】:
另一种选择:
get_ticker <- function(t) mean(sapply(d, "[[", t))
sapply(names(degree.l[[1]]), get_ticker)
【讨论】:
【参考方案3】:unlist
ing 之前,
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”代码并不总是在同一个地方。但我实际上可以将它们按相同的顺序排列,这样它就可以工作了。谢谢! 已修复,请参阅我的编辑。公平地说,您在此处的评论与您声明“这些代码在每个列表中保持相同” 的问题相反。要么保持不变,要么不保持不变,您需要明确问题,清楚地了解样本数据,并在评估结果时保持一致。【参考方案4】:data.table
选项使用 rbindlist
+ colMeans
> 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"]
【讨论】:
以上是关于列表列表中元素的平均值的主要内容,如果未能解决你的问题,请参考以下文章