计算数据框中所有列组合的均值

编程语言 2026-07-10

我有这个数据框:

 structure(list(ffw0 = c(8.60799803435064, 8.34185836453619, 8.07471159730671, 
7.82091460501107, 7.56772724986936), ffw1 = c(8.4937475524497, 
7.99877773077364, 7.40230840036861, 6.72275626701698, 5.96367684510491
), ffw2 = c(8.80102997756335, 8.73105190900452, 8.65977919061515, 
8.60566795392347, 8.55234042159471)), row.names = c(NA, -5L), class = "data.frame")



comb
      ffw0     ffw1     ffw2 year arima210 arima211      com
1 8.607998 8.493748 8.801030 2026 8.005053 7.841940 7.923496
2 8.341858 7.998778 8.731052 2027 7.692402 7.189011 7.440706
3 8.074712 7.402308 8.659779 2028 7.583277 6.761488 7.172382
4 7.820915 6.722756 8.605668 2029 7.545043 6.480838 7.012941
5 7.567727 5.963677 8.552340 2030 7.531630 6.296588 6.914109

我想对这些列的所有组合取均值。也就是说,例如取所有列的两两组合(x、y),对每一对按行计算其均值。然后取所有三元组合(x、y、z),对每个组合按行计算其均值,依此类推。

我在这个旧线程里看到了这个链接 link,似乎有些组合会产生非常大的均值,无法解释。

我可以用dplyr做到吗?还是有其他方法?

解决方案

Here's a base-R method.

comb2 <- combn(names(comb), 2, simplify = FALSE)
names(comb2) <- sapply(comb2, function(z) paste0("(", paste(z, collapse = ","), ")"))
res2 <- lapply(comb2, function(nm) rowMeans(subset(comb, select = nm)))
str(res2)
# List of 3
#  $ (ffw0,ffw1): Named num [1:5] 8.55 8.17 7.74 7.27 6.77
#   ..- attr(*, "names")= chr [1:5] "1" "2" "3" "4" ...
#  $ (ffw0,ffw2): Named num [1:5] 8.7 8.54 8.37 8.21 8.06
#   ..- attr(*, "names")= chr [1:5] "1" "2" "3" "4" ...
#  $ (ffw1,ffw2): Named num [1:5] 8.65 8.36 8.03 7.66 7.26
#   ..- attr(*, "names")= chr [1:5] "1" "2" "3" "4" ...

For a 3-way, we just change 2 to a 3:

comb3 <- combn(names(comb), 3, simplify = FALSE)
names(comb3) <- sapply(comb3, function(z) paste0("(", paste(z, collapse = ","), ")"))
res3 <- lapply(comb3, function(nm) rowMeans(subset(comb, select = nm)))

With those two, we can convert the lists to frames and then cbind them.

cbind(list2DF(res2), list2DF(res3))
#   (ffw0,ffw1) (ffw0,ffw2) (ffw1,ffw2) (ffw0,ffw1,ffw2)
# 1    8.550873    8.704514    8.647389         8.634259
# 2    8.170318    8.536455    8.364915         8.357229
# 3    7.738510    8.367245    8.031044         8.045600
# 4    7.271835    8.213291    7.664212         7.716446
# 5    6.765702    8.060034    7.258009         7.361248

Confirmation of one column (the second):

with(comb, (ffw0 + ffw2) / 2)
# [1] 8.704514 8.536455 8.367245 8.213291 8.060034

Note that part of the reason I combn(names(comb), ...) instead of combn(comb, ...) is that I want to form the names suggested in the question, e.g., (ffw0,ffw1). If you are less concerned about the naming, then using Friede's suggestion of combn(comb, ...) will certainly be shorter code and more direct, only requiring an additional naming step afterwards.

As a further example, if we want to create our own function that calls rowMeans and names the returned columns appropriately, we might do something like:

rowMeans2 <- function(x, sep = ",") {
  out <- list(rowMeans(x))
  names(out) <- paste(names(x), collapse = sep)
  list2DF(out)
}

combn(comb, 2, simplify = FALSE) |>
  lapply(rowMeans2) |>
  do.call(cbind, args = _)
#   ffw0,ffw1 ffw0,ffw2 ffw1,ffw2
# 1  8.550873  8.704514  8.647389
# 2  8.170318  8.536455  8.364915
# 3  7.738510  8.367245  8.031044
# 4  7.271835  8.213291  7.664212
# 5  6.765702  8.060034  7.258009

That's rather succinct, and easily extended for combn(comb, 3, ...) and on.

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章