R 对列表进行加权平均

R 对列表进行加权平均,r,lapply,R,Lapply,我有一个weight向量和一个与weight长度相同的列表。我想计算一下 使用权重对列表中每个元素进行加权平均,如下所示: wt <- c(0.3, 0.5, 0.2) temp_ls <- list(x = c(1, 2, 3, 4), y = c(5, 6, 7, 8), z = c(9, 10, 11, 12)) result_vec <- rep(length(temp_ls$x)) for(i in seq_along(temp_ls$x)){

我有一个
weight
向量和一个与
weight
长度相同的列表。我想计算一下 使用
权重对列表中每个元素进行加权平均,如下所示:

wt <- c(0.3, 0.5, 0.2)      
temp_ls <- list(x = c(1, 2, 3, 4), y = c(5, 6, 7, 8), z = c(9, 10, 11, 12))

result_vec <- rep(length(temp_ls$x))
   
for(i in seq_along(temp_ls$x)){
  
   temp_vec <- rep(NA, length(temp_ls))
    
   for(j in seq_along(temp_ls)){
      
     temp_vec[j] <- temp_ls[[j]][i]
      
   }
    
  result_vec[i] <- weighted.mean(temp_vec, wt)
}


result_vec
# 4.6 5.6 6.6 7.6
  

wt一个选项是
转置
列表
,循环
列表
,并应用
加权平均值

library(dplyr)
library(purrr)
temp_ls %>%
     transpose %>%
     map_dbl(~ weighted.mean(flatten_dbl(.x), w = wt))
#[1] 4.6 5.6 6.6 7.6
library(tibble)
library(tidyr)
library(data.table)
enframe(temp_ls) %>% 
  mutate(wt = wt) %>%
  unnest(c(value)) %>% 
  group_by(grp = rowid(name)) %>% 
  summarise(out = weighted.mean(value, w = wt), .groups = 'drop') %>% 
  pull(out)
#[1] 4.6 5.6 6.6 7.6

或者另一种方法是将
enframe
列表
设置为两列TIBLE,然后
unest
列表
元素,并通过
加权进行分组。平均值

library(dplyr)
library(purrr)
temp_ls %>%
     transpose %>%
     map_dbl(~ weighted.mean(flatten_dbl(.x), w = wt))
#[1] 4.6 5.6 6.6 7.6
library(tibble)
library(tidyr)
library(data.table)
enframe(temp_ls) %>% 
  mutate(wt = wt) %>%
  unnest(c(value)) %>% 
  group_by(grp = rowid(name)) %>% 
  summarise(out = weighted.mean(value, w = wt), .groups = 'drop') %>% 
  pull(out)
#[1] 4.6 5.6 6.6 7.6

或者在
堆栈
后使用
聚合
,在
base R中插入两列数据.frame

aggregate(values ~ grp, transform(stack(temp_ls), 
   grp = ave(seq_along(ind), ind, FUN = seq_along)),
      FUN = weighted.mean, w = wt)
# grp values
#1   1    4.6
#2   2    5.6
#3   3    6.6
#4   4    7.6

或者使用
mapply

do.call(mapply, c(FUN = function(...) weighted.mean(c(...), w = wt), 
     unname(temp_ls)))
#[1] 4.6 5.6 6.6 7.6
或使用
Map

unlist(do.call(Map, c(f = function(...) weighted.mean(c(...), 
            w = wt), unname(temp_ls))))

或者更紧凑

apply(do.call(cbind, temp_ls), 1, weighted.mean, w = wt)
#[1] 4.6 5.6 6.6 7.6

我认为在这种情况下,使用不同的数据结构会更容易,也就是说,将要操作的值按行或列分组,而不是跨向量拆分。