【问题标题】:creating a dataframe of means of 5 randomly sampled observations创建一个包含 5 个随机抽样观测值的数据框
【发布时间】:2020-06-11 18:20:37
【问题描述】:

我目前正在阅读“面向数据科学家的实用统计”,并在他们演示一些代码时跟随 R 学习。有一段代码我特别难以遵循其逻辑,并希望有人能提供帮助。有问题的代码是创建一个包含 1000 行的数据框,其中每个观察值是从数据框 loans_income 中随机抽取的 5 个收入值的平均值。但是,我对代码的逻辑感到困惑,因为 tapply() 函数和嵌套的 rep() 语句相当复杂。

创建相关数据框的代码如下:

samp_mean_5 <- data.frame(income = tapply(sample(loans_income$income,1000*5),
                                          rep(1:1000,rep(5,1000)),
                                          FUN = mean),
           type='mean_of_5')

特别是,我对嵌套的rep() 语句和sample() 函数的1000*5 部分感到困惑。任何理解代码逻辑的帮助将不胜感激!

作为参考,原始数据集loans_income 仅具有包含 50,000 个收入值的单列。

【问题讨论】:

    标签: r logic sample tapply rep


    【解决方案1】:

    您在一个向量中拥有 50,000 个 loan_income。让我们分解你的代码:

    tapply(sample(loans_income$income,1000*5),
           rep(1:1000,rep(5,1000)),
           FUN = mean)
    

    我将 1000 替换为 10,将收入替换为随机数,这样更容易解释。我还设置了set.seed(1),这样结果就可以复现了。

    1. sample(loans_income$income,1000*5)
      我们从您的向量中随机抽取 50 份收入,无需更换。它们(暂时)被放入长度为 50 的向量中,因此输出如下所示:
    > sample(runif(50000),10*5)
     [1] 0.73283101 0.60329970 0.29871173 0.12637654 0.48434952 0.01058067 0.32337850
     [8] 0.46873561 0.72334215 0.88515494 0.44036341 0.81386225 0.38118213 0.80978822
    [15] 0.38291273 0.79795343 0.23622492 0.21318431 0.59325586 0.78340477 0.25623138
    [22] 0.64621658 0.80041393 0.68511759 0.21880083 0.77455662 0.05307712 0.60320912
    [29] 0.13191926 0.20816298 0.71600799 0.70328349 0.44408218 0.32696205 0.67845445
    [36] 0.64438336 0.13241312 0.86589561 0.01109727 0.52627095 0.39207860 0.54643661
    [43] 0.57137320 0.52743012 0.96631114 0.47151170 0.84099503 0.16511902 0.07546454
    [50] 0.85970500
    
    1. rep(1:1000,rep(5,1000))
      现在我们正在创建一个长度为 50 的索引向量:
    > rep(1:10,rep(5,10))
    [1]  1  1  1  1  1  2  2  2  2  2  3  3  3  3  3  4  4  4  4  4  5  5  5  5  5  6  6  6
    [29]  6  6  7  7  7  7  7  8  8  8  8  8  9  9  9  9  9 10 10 10 10 10
    

    那些索引“分组”来自步骤 1 的样本。所以基本上这个向量告诉R“样本向量”的前 5 个条目属于一起(索引 1),接下来的 5 个条目属于一起(索引 2)等等。

    1. FUN = mean
      只需对数据应用mean-function。

    2. tapply
      所以tapply 获取采样数据(sample-part)并按第二个参数(rep()-part)对它们进行分组,并对每个组应用mean-函数。

    如果你熟悉 data.frames 和 dplyr 包,看看这个(只显示前 10 行):

    set.seed(1)
    df <- data.frame(income=sample(runif(5000),10*5), index=rep(1:10,rep(5,10)))
           income index
    1  0.42585569     1
    2  0.16931091     1
    3  0.48127444     1
    4  0.68357403     1
    5  0.99374923     1
    6  0.53227877     2
    7  0.07109499     2
    8  0.20754511     2
    9  0.35839481     2
    10 0.95615917     2
    

    我将索引附加到随机数(您的income)。现在我们计算每组的平均值:

    df %>% 
      group_by(index) %>%
      summarise(mean=mean(income))
    

    这给了我们

    # A tibble: 10 x 2
       index  mean
       <int> <dbl>
     1     1 0.551
     2     2 0.425
     3     3 0.827
     4     4 0.391
     5     5 0.590
     6     6 0.373
     7     7 0.514
     8     8 0.451
     9     9 0.566
    10    10 0.435
    

    比较一下

    set.seed(1)
    tapply(sample(runif(5000),10*5),
           rep(1:10,rep(5,10)),
           mean)
    

    产生基本相同的结果:

            1         2         3         4         5         6         7         8         9 
    0.5507529 0.4250946 0.8273149 0.3905850 0.5902823 0.3730092 0.5143829 0.4512932 0.5658460 
           10 
    0.4352546
    

    【讨论】:

    • 感谢您的回复。 (1.) 将 '1000*5' 作为示例函数的第二个参数而不是仅键入 '5000' 是否有任何约定? (或 50,在您的示例中)
    • (2.) 第二个嵌套的 rep() 函数满足 rep() 函数的哪个参数?查看文档,它是“时间”参数吗?我知道这一步的总体目的是创建一个索引向量,但我想我正在努力思考它是如何做到的
    • 我一直想深入研究 dplyr 包,因为到目前为止我对它的了解还很肤浅。但它看起来非常有用!谢谢你的建议
    • @cliftjc1 (1) 我不知道任何约定。我猜1000*5 应该明确表明您正在为 1000 个观察值绘制每 5 个样本。将其分解为 1000*5 可以让您更轻松地(出于建模目的)将其替换为 n*m 并使用可变数量的样本和观察值。
    • (2) rep() 的第二个参数是时间参数。因此,对于第一个参数的每个条目,它包含重复次数(在这种情况下:每个条目将重复 5 次)。看看rep(1:10, 1:10)
    猜你喜欢
    • 2021-04-01
    • 2018-08-20
    • 1970-01-01
    • 2015-05-12
    • 2011-08-06
    • 1970-01-01
    • 2021-03-01
    • 1970-01-01
    • 2020-07-29
    相关资源
    最近更新 更多