【问题标题】:R - Frequency histogram from sampling: efficiency and moreR - 采样频率直方图:效率等
【发布时间】:2018-06-08 05:30:43
【问题描述】:

我是一名大学生,开始为考试探索 R。 抱歉标题含糊不清,因为我有很多与这篇文章相关的问题。

我遇到了对男性 (M) 或女性 (F) 人群进行抽样的问题。我希望定义一个函数,该函数可以获取该人口中男性和女性的数量,然后创建大小为 sample.size 的样本 sample.number 并返回一个数据框,其中包含女性样本占样本总大小的比例,其中相关频率。

我很肯定有一种简单且经过良好优化的方法可以做到这一点,但我编写了一个(几乎)工作的小函数:

senators <- function(Fem = 13, 
                 Mal = 87, 
                 sample.size = 10, 
                 sample.number = 100){

pop <- c(rep("F", Fem), rep("M", Mal)) # I create the population base

popsa <- list(NA)           # I make some empty variables used later
popsa.factor <- list(NA)    # Not sure if this passage is even needed...
popsa.proportion <- list(NA)

这是一个for 循环。我读过for 循环确实是低效的方法。有没有更好的办法?

for(i in 1:sample.number){
  popsa[[i]] <- sample(pop, sample.size, replace = TRUE)
  popsa.factor[[i]] <- table(factor(popsa[[i]], levels = c("M", "F")))
  popsa.proportion[[i]] <- popsa.factor[[i]][2]/sample.size
  }

我首先为列表popsa 的每个元素分配一个样本,然后使用popsa 从每个样本创建一个表,并将其存储在popsa.factor 中。然后我计算女性占总数的比例并将其存储在popsa.proportion 中。这个for 循环对我来说似乎超级混乱,处理大量样本真的很慢。有没有更好、更有效的方法来完成我在这里所做的事情?

popsa.unlisted <- unlist(popsa.proportion)
popsa.frequency <- table(popsa.unlisted)

popsa.frame <- data.frame(Level = as.numeric(names(popsa.frequency)), 
                          Freq =  as.numeric(popsa.frequency))
return(popsa.frame)
} # This closes the function call

然后我取消列出 popsa.proportion 以获取向量中的每个比例,并将这些值列出以获取频率,并将它们存储到 popsa.frequency。现在我尝试通过欺骗并将popsa.frequency 的名称转换为数字并将它们存储为数据框的第一列,将因子popsa.frequency 转换为数据框。然后函数返回popsa.frame,正如我想要的那样。

popsa.frame 仍然在其第一列 (Level) 中继承了 popsa.frequency 的因子属性。我怎样才能改变这个?我应该吗?

由于这些是样本分布的频率,我想从这个数据帧创建一个直方图,尽管hist() 只接受数字向量,所以popsa.frame 不是一个有效的对象。不过,plot(popsa.frame) 或多或少会返回我想要的东西。如何创建这样的直方图?

编辑:按照下面的标记答案,我还提出了如何简单地将函数创建的数据框转换为 hist() 可以实际用于创建频率直方图的对象(尽管使用条形图会产生更多或更少相同的图表,并且可能是显示此类结果的统计上更正确的方式):

result <- senators(Fem=13,Mal=87,sample.size=50,sample.number=10000)

raw <- sapply(1:length(result$Level), function(x){
  rep(result$Level, result$Freq)
})

hist(raw)

【问题讨论】:

  • 那么,你想为你data.frame的每一列做直方图吗?
  • 不完全是,我希望创建一个直方图,其中“y”轴是频率,“x”轴是比例值。 @patL 类似于 This,但带有直方图的列。

标签: r performance histogram


【解决方案1】:

列表和 for 循环的创建存在一些性能瓶颈。我能够使用sapply 删除for loop 和一些临时变量。

我仍在返回数据名声,另一个选项将返回向量答案,只需将结果传递给您的最终绘图的直方图绘图函数。

senators <- function(Fem = 13, 
                     Mal = 87, 
                     sample.size = 10, 
                     sample.number = 100){

  pop <- c(rep("F", Fem), rep("M", Mal)) # I create the population base

  answer<-sapply(1:sample.number, function(x){popsa <- sample(pop, sample.size, replace = TRUE);
                                            length(popsa[popsa=="F"])/sample.size})

popsa.frequency <- table(answer)

popsa.frame <- data.frame(Level = as.numeric(names(popsa.frequency)), 
                          Freq =  as.numeric(popsa.frequency))
return(popsa.frame)
} 

senators()   

【讨论】:

    【解决方案2】:

    您的函数有一些默认值,只需执行senators(),就可以创建data.frame

    按照你的数据我会做的:

    df <- senators() # using default values
    plot(df, type="h", lwd = 5, lend=1) # type changes your plot type while lwd changes line sizes, while lend would give squared aspect yo your bars.
    

    查看?plot 以了解您可以执行的绘图类型。另外,你可以通过?par查看如何更改参数。

    P.S.:查看post 了解线宽详细信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多