将多个 csv 文件的标准偏差合并到一个文件中

Standard Deviation across multiple csv files into a single file

我想汇总 1000 个文件,40 行 20 列。我想生成两个摘要文件,每个都保留原始尺寸 40x20。第一个文件包含均值,第二个文件包含文件中所有 1000 个值的每个位置的标准差。从下面的 post 中,我找到了一种非常优雅的方法来计算所有文件的平均值(感谢@josliber),但我正在努力将该逻辑扩展到标准差。

我要将数据加载到数据帧列表中

csvs <- lapply(list.files(pattern="weather*.csv"), read.csv)

Reduced 可以很好地获取我的平均摘要文件。我们可以做一些类似(或不同)的事情来得到我的标准偏差吗?

Reduce("+", csvs) / length(csvs)

您可以再次做类似的事情,但使用标准偏差计算背后的基本数学:

# get the means as before
means <- Reduce( "+", csvs ) / length( csvs )

# make a new list of deviations from that known mean
st.dev <- lapply( csvs, function(x) ( x - means )^2 )

# use the list of deviations to calculate the standard deviation matrix
st.dev <- sqrt( Reduce( "+", st.dev ) / length( st.dev ) )

有关此处数学的详细信息,请在维基百科中搜索 "Standard deviation"。

另一个选项会打开其他几个统计选项。

如果将 40x20 data.frames 的列表转换为 40x20x1000 数组,则可以 apply 跨每个 40x20 "tubes" 钻入第 3 个维度。

使用三个 2x4 矩阵的样本:

set.seed(42)
lst <- lapply(1:3, function(ign) matrix(sample(8), nrow=2))
lst
# [[1]]
#      [,1] [,2] [,3] [,4]
# [1,]    8    2    3    4
# [2,]    7    5    6    1
# [[2]]
#      [,1] [,2] [,3] [,4]
# [1,]    6    3    7    8
# [2,]    5    4    1    2
# [[3]]
#      [,1] [,2] [,3] [,4]
# [1,]    8    3    4    2
# [2,]    1    6    7    5

使用abind库,我们可以任意绑定第三个dim。 (假设您的 data.frames 已被捕获在列表中,这就是您要开始的地方。abind 与相同大小的 data.frames 一样适用于矩阵。)

library(abind)
ary <- abind(lst, along = 3)
dim(ary)
# [1] 2 4 3

现在 运行 沿每个 "tube" 任意函数(相对于 "row" 或 "column",因为大多数人认为 apply 用于)。例如,给定三层中的 [1,1] 值为 8、6 和 8,我们期望得到以下统计信息:

mean(c(8,6,8))
# [1] 7.333333
sd(c(8,6,8))
# [1] 1.154701

现在,使用 apply:

apply(ary, 1:2, mean)
#          [,1]     [,2]     [,3]     [,4]
# [1,] 7.333333 2.666667 4.666667 4.666667
# [2,] 4.333333 5.000000 4.666667 2.666667
apply(ary, 1:2, sd)
#          [,1]      [,2]     [,3]     [,4]
# [1,] 1.154701 0.5773503 2.081666 3.055050
# [2,] 3.055050 1.0000000 3.214550 2.081666

假设每层中的索引具有有意义的可比性,这会打开 1000 个相同大小 data.frames 的更多统计聚合。您也许可以设计一个工作模型来确定 Reduce 的中位数或其他百分位数,但是对于第 90 个百分位数来说,apply(ary, 1:2, quantile, 0.9) 很容易做到。