【问题标题】:Calculating standard deviation of variables in a large list in R计算R中大型列表中变量的标准差
【发布时间】:2016-07-21 02:11:23
【问题描述】:

我有一个大列表,其中包含 1000 个相同变量和相同长度的列表。

我的目标是计算大列表中所有列表的均值、标准差和标准误差。

我已经使用 Reduce() 计算了变量的平均值,但我不知道如何对标准差做同样的事情。

我的列表如下所示:

large.list <- vector('list', 1000)

for (i in 1:1000) {
    large.list[[i]] <- as.data.frame(matrix(c(1:4), ncol=2))
}

large.list

[[1]]
   V1  V2
1   1   3
2   2   4

[[2]]
   V1  V2
1   1   3
2   2   4

[[3]]
   V1  V2
1   1   3
2   2   4

......

[[1000]]
   V1  V2
1   1   3
2   2   4      

要计算平均值,我会这样做:

list.mean <- Reduce("+", large.list) / length(large.list)

list.mean

   V1   V2
1   1    3
2   2    4

这是一个大列表的过度简化版本,但我如何计算列表范围的标准差和标准误差,就像我为平均值所做的那样?

非常感谢您!

【问题讨论】:

标签: r


【解决方案1】:

如果你留在Reduce(),你必须做一点统计:

var(x) = E(x^2) - (E(x))^2

请注意,您已经将E(x) 设置为list.mean。要获取E(x^2),也很简单:

list.squared.mean <- Reduce("+", lapply(large.list, "^", 2)) / length(large.list)

那么方差是:

list.variance <- list.squared.mean - list.mean^2

标准差只是

list.sd <- sqrt(list.variance)

但是,更有效的解决方案是使用tapply()

vec <- unlist(large.list, use.names = FALSE)
DIM <- dim(large.list[[1]])
n <- length(large.list)

list.mean <- tapply(vec, rep(1:prod(DIM),times = n), mean)
attr(list.mean, "dim") <- DIM
list.mean <- as.data.frame(list.mean)

list.sd <- tapply(vec, rep(1:prod(DIM),times = n), sd)
attr(list.sd, "dim") <- DIM
list.sd <- as.data.frame(list.sd)

【讨论】:

  • 非常感谢!第二种解决方案确实效率更高。一个缺点是删除了行名和列名。我添加了 rownames 和 colnames 函数来解决这个问题。再次感谢!
【解决方案2】:

如果我可以提出替代方案,您可以将列表转换为 3 维矩阵,然后使用 apply() 生成输出。

下面是如何变换列表(假设维度规律):

m <- do.call(cbind,lapply(large.list,as.matrix));
m <- array(m,c(nrow(m),ncol(m)/length(large.list),length(large.list)));

下面是如何在矩阵上使用apply()

apply(m,1:2,mean);
##      [,1] [,2]
## [1,]    1    3
## [2,]    2    4
apply(m,1:2,sd);
##      [,1] [,2]
## [1,]    0    0
## [2,]    0    0

【讨论】:

    【解决方案3】:

    这里是基于将列表重塑为 data.table 的解决方案。我们基本上是从每个子列表中提取索引 i 的值来创建一个向量。

    ll <- unlist(large.list)
    DX <- data.table(V1= ll[c(T,F,F,F)],
                     V2= ll[c(F,T,F,F)],
                     V3= ll[c(F,F,T,F)],
                     V4= ll[c(F,F,F,T)])
    

    那么所有的计算都是直截了当的:

    mm <- DX[,lapply(.SD,mean)]
    sdd <- DX[,lapply(.SD,sd)]
    

    【讨论】:

      猜你喜欢
      • 2013-10-04
      • 1970-01-01
      • 2017-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-27
      • 2016-04-17
      • 2013-06-03
      相关资源
      最近更新 更多