R - 采样频率直方图:效率等



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

我遇到了对男性(M)或女性(F)人群进行抽样的问题。我希望定义一个函数,该函数可以获取该总体中的男性和女性数量,然后创建大小为sample.sizesample.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)

列表和 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()   

您的函数具有一些默认值,只需执行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来查看如何更改参数。

PS:查看这篇文章以了解线宽详细信息。

最新更新