1

我有以下代码选择 4 行 iris 1000x,并取每个 4 行样本的平均值:

library(dplyr)

iris<- iris

storage<- list()


counter<- 0
for (i in 1:1000) {
  # sample 3 randomly selected transects 100 time
  tempsample<- iris[sample(1:nrow(iris), 4, replace=F),]

  storage[[i]]=tempsample

  
  counter<- counter+1
  print(counter)
}

# Unpack results into dataframe 
results<- do.call(rbind, storage)
View(results)

results_2<- as.data.frame(results)
results_2<- results_2 %>% mutate(Aggregate = rep(seq(1,ceiling(nrow(results_2)/4)),each = 4))
# View(results_2)


final_results<- aggregate(results_2[,1:4], list(results_2$Aggregate), mean)
# View(final_results)

我想计算每列相对于其真实总体参数的偏差。例如使用SimDesign's bias()

library(SimDesign)
(bias(final_results[,2:5], parameter=c(5,3,2,1), type='relative'))*100

在此代码中,参数的值是假设的真实弹出。数据框中每一列的值。我想以 100 倍的速度执行此过程,以获取数据框中每个变量的偏差估计分布。但是,我不确定如何将所有这些放入 for 循环中(我认为这是要走的路),所以最终输出是一个数据帧,每个 iris 变量都有 100 行偏差测量值。

对此的任何帮助将不胜感激。

#------------------------------------------

更新

尝试为分层样本而不是随机样本运行相同的代码会给我以下错误: *Error in [.data.table(setDT(copy(iris)), as.vector(sapply(1:1000, function(X) stratified( iris, : i is invalid type (matrix). 也许将来 2 列矩阵可以返回 DT 的元素列表 * 我认为这可能与 setDT 有关?

这是以下代码的结果:

do.call(rbind,lapply(1:100, function(x) {
  bias(
    setDT(copy(iris))[as.vector(sapply(1:1000, function(X) stratified(iris,group="Species", size=1)))][
      , lapply(.SD, mean), by=rep(c(1:1000),4), .SDcols=c(1:4)][,c(2:5)],
    parameter=c(5,3,2,1), 
    type='relative'
  )
}))

我研究了使用以下建议的代码:

get_samples <- function(n, sampsize=4) {
  rbindlist(lapply(1:n, function(x) { 
    splitstackshape::stratified(iris, group="Species",sampsize)[, id:=x]   }))[
      , lapply(.SD, mean), by=.(Species, id)] }

我想我理解这个函数在做什么(选择 4 行分层的虹膜,按物种取每列的平均值),但我不知道如何将它应用于原来的问题(4 * 1000)* 100 来测试偏见(我对此很陌生,如果我遗漏了一些明显的东西,我深表歉意)。

4

2 回答 2

1

由于您正在使用mutate,您可以考虑使用tidyverse.

map_df(1:1000, ~ sample_n(iris, 4, replace = FALSE)) %>%
glimpse() %>%
mutate(Aggregate_col = rep(seq(1, ceiling(n() / 4)), each = 4)) %>%
glimpse() %>%
select(starts_with("Sepal"),
       starts_with("Petal"),
       matches("Aggregate")) %>%
group_by(Aggregate_col) %>%
summarise(across(.cols = everything(), ~ mean(.x, na.rm = TRUE)))

笔记:

  • 在下面的示例中,您的第一个循环被替换为:

    map_df(1:1000, ~ sample_n(iris, 4, replace = FALSE))
    
  • map_x可以用来迭代一个列表,或者在这种情况下是一个整数向量1:1000,如果唯一的目的是重复调用函数,并将结果绑定到所需的格式,在这种情况下是 a data.frame

  • 您可以glimpse在数据转换管道中利用 while 来避免View重复调用

  • select提供一种按名称或部分匹配选择列的可读方式。这通常比在添加/删除变量时按索引选择列更安全

于 2022-02-23T08:55:50.337 回答
1

这是一种方法。我对您的代码进行了一些小的更改,并将其包装在一个函数中。然后,使用lapply一个序列说1:10or 1:100,每次运行你的函数,并将结果biasSimDesign包中提供给你的函数。然后行绑定结果列表

library(dplyr)

get_samples <- function(df, size=4, n=1000) {

  storage<- list()
  counter<- 0
  
  for (i in 1:1000) {
    tempsample<- df[sample(1:nrow(df), size, replace=F),]
    storage[[i]]=tempsample
    counter<- counter+1
  }
  
  results<- do.call(rbind, storage)
  results_2<- as.data.frame(results)
  results_2<- results_2 %>% mutate(Aggregate = rep(seq(1,ceiling(nrow(results_2)/size)),each = size))
  final_results<- aggregate(results_2[,1:size], list(results_2$Aggregate), mean)
  return(final_results)
}


iris=iris

replicates = lapply(1:10, function(x) {
  result = get_samples(iris)
  (bias(result[,2:5], parameter=c(5,3,2,1), type='relative'))*100
})

replicates = do.call(rbind, replicates)

输出:

      Sepal.Length Sepal.Width Petal.Length Petal.Width
 [1,]     41.50617    3.292500     86.77408    8.859333
 [2,]     43.26058    2.763500     90.20758   10.825917
 [3,]     43.46642    3.551750     90.11767   10.576250
 [4,]     41.94683    2.970833     86.89625    8.817000
 [5,]     42.08733    3.380917     86.78642    8.996667
 [6,]     42.13050    2.942250     88.02983    9.707500
 [7,]     43.07383    2.775500     89.04583   10.102083
 [8,]     44.10192    2.895167     91.27208   11.188500
 [9,]     41.29408    2.314750     87.59208    9.244333
[10,]     42.77450    2.781583     90.37342   10.789500

快速解决问题

library(SimDesign)
library(data.table)

do.call(rbind,lapply(1:100, function(x) {
  bias(
    setDT(copy(iris))[as.vector(sapply(1:1000, function(X) sample(1:nrow(iris),4)))][
      , lapply(.SD, mean), by=rep(c(1:1000),4), .SDcols=c(1:4)][,c(2:5)],
    parameter=c(5,3,2,1), 
    type='relative'
  )
}))
于 2022-02-23T01:47:56.580 回答