首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何有效地按组对样本数据进行细分?

如何有效地按组对样本数据进行细分?
EN

Stack Overflow用户
提问于 2013-06-04 15:33:03
回答 2查看 635关注 0票数 2

我确实有一个类似的问题,在this question中有解释。与这个问题类似,我有一个数据框,它有3列(id、group、value)。我想从每个组中取n个样本进行替换,并产生一个较小的数据帧,每个组中有n个样本。

然而,我在一个模拟代码中做了数百个子样本,基于ddply的解决方案在我的代码中使用起来非常慢。我试图重写一个简单的代码,看看是否可以获得更好的性能,但它仍然很慢(如果不是更差,也不会比ddply解决方案更好)。下面是我的代码。我想知道是否可以改进它的性能

代码语言:javascript
运行
复制
#Producing example DataFrame
dfsize <- 10
groupsize <- 7
test.frame.1 <- data.frame(id = 1:dfsize, group = rep(1:groupsize,each = ceiling(dfsize/groupsize))[1:dfsize], junkdata = sample(1:10000, size =dfsize))


#Main function for subsampling
sample.from.group<- function(df, dfgroup, size, replace){
  outputsize <- 1
  newdf <-df # assuming a sample cannot be larger than the original
  uniquegroups <- unique(dfgroup)
  for (uniquegroup in uniquegroups){
    dataforgroup <- which(dfgroup==uniquegroup)
    mysubsample <- df[sample(dataforgroup, size, replace),]
    sizeofsample <- nrow(mysubsample)
    newdf[outputsize:(outputsize+sizeofsample-1), ] <- mysubsample
    outputsize <- outputsize + sizeofsample
  }
  return(newdf[1:(outputsize-1),])
}

#Using the function
sample.from.group(test.frame.1, test.frame.1$group, 100, replace = TRUE)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-06-04 21:10:43

这里有两个基于plyr的解决方案:

代码语言:javascript
运行
复制
library(plyr)

dfsize <- 1e4
groupsize <- 7
testdf <- data.frame(
  id = seq_len(dfsize),
  group = rep(1:groupsize, length = dfsize),
  junkdata = sample(1:10000, size = dfsize))

sample_by_group_1 <- function(df, dfgroup, size, replace) {
  ddply(df, dfgroup, function(x) {
    x[sample(nrow(df), size = size, replace = replace), , drop = FALSE]
  })
}

sample_by_group_2 <- function(df, dfgroup, size, replace) {
  idx <- split_indices(df[[dfgroup]])
  subs <- lapply(idx, sample, size = size, replace = replace)

  df[unlist(subs, use.names = FALSE), , drop = FALSE]
}

library(microbenchmark)
microbenchmark(
  ddply = sample_by_group_1(testdf, "group", 100, replace = TRUE),
  plyr = sample_by_group_2(testdf, "group", 100, replace = TRUE)
)

# Unit: microseconds
#   expr  min   lq median   uq   max neval
#  ddply 4488 4723   5059 5360 36606   100
#   plyr  443  487    507  536 31343   100

第二种方法要快得多,因为它在一个步骤中完成了子集-如果你可以在一个步骤中弄清楚如何做到这一点,它通常是获得更好性能的任何简单方法。

票数 3
EN

Stack Overflow用户

发布于 2013-06-04 16:32:38

我认为这更干净,也可能更快:

代码语言:javascript
运行
复制
z <- sapply(unique(test.frame.1$group), FUN= function(x){ 
            sample(which(test.frame.1$group==x), 100, TRUE)
            })
out <- test.frame.1[z,]
out
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16912186

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档