【问题标题】:Standard Deviation across multiple csv files into a single file跨多个 csv 文件到单个文件的标准偏差
【发布时间】:2017-07-11 18:03:06
【问题描述】:

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

Average multiple csv files into 1 averaged file in r

我正在将数据加载到数据框列表中

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

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

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

【问题讨论】:

    标签: r csv reduce


    【解决方案1】:

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

    # 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 ) )
    

    有关此处数学的详细信息,请在 Wikipedia 中搜索“标准差”。

    【讨论】:

    • 这真是太棒了,感谢统计数据审查。我说得很有道理。
    【解决方案2】:

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

    如果您将 40x20 data.frames 列表转换为 40x20x1000 数组,您可以 apply 穿过每个 40x20“管”钻入第 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
    

    现在沿着每个“管”运行任意函数(相对于“行”或“列”,大多数人认为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 确定中位数或其他百分位数,但很容易做到(例如)apply(ary, 1:2, quantile, 0.9) 第 90 个百分位数。

    【讨论】:

    • 非常感谢这个解决方案!
    猜你喜欢
    • 2015-06-08
    • 2021-10-16
    • 2017-06-07
    • 2015-04-07
    • 1970-01-01
    • 2016-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多