【问题标题】:Getting the mean of 2 variables across a list of lists in R在R中的列表中获取2个变量的平均值
【发布时间】:2020-10-21 00:15:18
【问题描述】:

在下面我的replicate() 调用之后,我想知道如何在列表中获得'Estimate''Std. Error'x1x2mean

foo <- function(){
x1 <- rnorm(20) ; x2 <- rnorm(20,2); y <- rnorm(20,3)
coef(summary(lm(y~x1+x2)))[,1:2]  }

# Now replicate foo():

replicate(2, foo(), simplify = F) # How to get the mean of 'Estimate' and 'Std. Error' for 'x1' and 'x2' after loop

 ### OUTPUT:

[[1]]
              Estimate  Std. Error
(Intercept)  3.1356507  0.4874282
x1          -0.3408958  0.2033072
x2          -0.1335315  0.2513356

[[2]]
             Estimate Std. Error
(Intercept) 2.5574090  0.4354596
x1          0.0850336  0.3101341
x2          0.2348902  0.1754149

【问题讨论】:

  • 如果您将该列表存储在像x 这样的变量中,您可以使用do.call('+', x) / length(x)。这将取矩阵中所有元素的平均值。您的列表是否总是有 2 项?
  • @MrFlick,它可以有更多,我也愿意使用任何包?

标签: r list function loops lapply


【解决方案1】:

首先,我们修复列表,以便我们可以看到不同方法的结果:

set.seed(111)
dat = replicate(2, foo(), simplify = F)

dat
[[1]]
               Estimate Std. Error
(Intercept)  3.47644151  0.4100162
x1          -0.04314488  0.2769444
x2          -0.04946731  0.1860911

[[2]]
               Estimate Std. Error
(Intercept)  2.96378594  0.5265807
x1           0.22268874  0.3517643
x2          -0.04437585  0.2468499

使用基础 R“减少”:

Reduce(`+`,dat)/length(dat)
               Estimate Std. Error
(Intercept)  3.22011373  0.4682984
x1           0.08977193  0.3143544
x2          -0.04692158  0.2164705

使用咕噜声:

library(purrr)
reduce(dat,`+`)/length(dat)

               Estimate Std. Error
(Intercept)  3.22011373  0.4682984
x1           0.08977193  0.3143544
x2          -0.04692158  0.2164705

【讨论】:

  • 它们不等价...如果您有 3 个列表,您会看到 do.call 会抛出错误。假设您有一个函数f(x,y),并且您想应用到a,b and cReduce(f,list(a,b,c)) 会做f ( f(a,b), c)
  • do.call 仅适用于需要一个或多个输入的函数,因此使用 do.call(f,list(a,b,c)) 将执行 f(a,b,c...) 并且您可以看到为什么“+”不起作用,因为它适用于2个变量
  • @rnorouzian,这是一个很好的问题.. 希望我的错误听起来不要太抽象 =_='
【解决方案2】:

tidyverse 解决方案可能是

library(tidyverse)
replicate(2, foo(), simplify = FALSE) %>% #could use purrr::rerun here
  map_df(as_tibble, rownames = "coef") %>% 
  group_by(coef) %>% 
  summarise(across(.fns = mean))

  coef        Estimate `Std. Error`
  <chr>          <dbl>        <dbl>
1 (Intercept)    3.58         0.514
2 x1            -0.131        0.206
3 x2            -0.223        0.224

【讨论】:

  • 第一行可能是rerun(.n = 2, foo()) 在这里没有太大的优势,但 .id 参数可能非常有用。你需要 dplyr v 1.0.0 来完成。替换 summarise_at
  • dplyr 1.0.0 尚未在 tidyverse 中更新。当我单独更新dplyr 时,它带来了很多问题。因此,此时tidyverse 中基本上不存在across
  • 您可以只使用常规汇总 - 例如summarise(e = mean(Estimate), s = mean(Std。错误)
【解决方案3】:

使用base R,我们也可以转换为array,得到mean。如果存在,它也会处理NA 元素

apply(array(unlist(dat), c(3, 2, 2)), 1:2, mean, na.rm = TRUE)
#          [,1]      [,2]
#[1,]  3.22011373 0.4682984
#[2,]  0.08977193 0.3143544
#[3,] -0.04692158 0.2164705

数据

set.seed(111)
dat <- replicate(2, foo(), simplify = FALSE)

【讨论】:

  • 谢谢,Arun,我想一点一点地学习tidyverese。它使用更一致的语法。
  • @rnorouzian 我以为你只想要一个基本的 R 解决方案(一如既往)
  • 你说得对,但我已经开始探索tidyverse
猜你喜欢
  • 2021-08-03
  • 2013-07-22
  • 2022-01-13
  • 2021-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多