簡體   English   中英

從數據框中按類別選擇隨機行?

[英]Selecting random rows by category from a data frame?

我有一個數據框如下:

Category Name Value

我如何選擇每個類別5個隨機名稱? 使用sample返回隨機行,使用所有行作為可能的候選。 但是,我想指定每個類別的隨機行數。 有什么建議么?

更新 :我願意使用ddply

沒有測試用例的最佳猜測:

  do.call( rbind, lapply( split(dfrm, df$cat) ,
                         function(df) df[sample(nrow(df), 5) , ] )
          )

用Jonathan的數據測試:

> do.call( rbind, lapply( split(df, df$Category) ,
+                          function(df) df[sample(nrow(df), 5) , ] )
+           )

      Category Name      Value   
1.8          1    8 -0.2496109   #  useful side-effect of labeling source group
1.15         1   15 -0.4037368
1.17         1   17 -0.4223724
1.12         1   12 -0.9359026
1.18         1   18  0.3741184
2.37         2   37  0.3033610
2.34         2   34 -0.4517738
2.36         2   36 -0.7695923
snipped remainder

如果您想從每個類別中獲得相同數量的項目,這很容易:

df[unlist(tapply(1:nrow(df),df$Category,function(x) sample(x,3))),]

例如,我生成的df如下:

df <- data.frame(Category=rep(1:5,each=20),Name=1:100,Value=rnorm(100))

然后我從我的代碼中得到以下內容:

> df[unlist(tapply(1:nrow(df),df$Category,function(x) sample(x,3))),]
    Category Name       Value
5          1    5  0.25151044
20         1   20  1.52486482
18         1   18  0.69313462
30         2   30  0.73444185
27         2   27  0.24000427
39         2   39 -0.10108203
46         3   46 -0.37200574
49         3   49 -1.84920469
43         3   43  0.35976388
68         4   68  0.57879516
76         4   76 -0.11049302
64         4   64 -0.13471303
100        5  100  0.95979408
95         5   95 -0.01928741
99         5   99  0.85725242

如果你想從每個類別中獲得不同數量的行,那將會更復雜。

在過去,我使用了一些我為“sampling”包中的一些函數編寫的包裝器。

這是功能:

strata.sampling <- function(data, group, size, method = NULL) {
  #  USE: 
  #   * Specify a data.frame and grouping variable.
  #   * Decide on your sample size. For a sample proportional to the 
  #     population, enter "size" as a decimal. For an equal number of 
  #     samples from each group, enter "size" as a whole number. For
  #     a specific number of samples from each group, enter the numbers
  #     required as a vector.

  require(sampling)
  if (is.null(method)) method <- "srswor"
  if (!method %in% c("srswor", "srswr")) 
    stop('method must be "srswor" or "srswr"')
  temp <- data[order(data[[group]]), ]
  ifelse(length(size) > 1,
         size <- size, 
         ifelse(size < 1,
                size <- round(table(temp[group]) * size),
                size <- rep(size, times=length(table(temp[group])))))
  strat = strata(temp, stratanames = names(temp[group]), 
                 size = size, method = method)
  getdata(temp, strat)
}

以下是如何使用它:

# Sample data --- Note each category has a different number of observations
df <- data.frame(Category = rep(1:5, times = c(40, 15, 7, 13, 25)), 
                 Name = 1:100, Value = rnorm(100))

# Sample 5 from each "Category" group
strata.sampling(df, "Category", 5)
# Sample 2 from the first category, 3 from the next, and so on
strata.sampling(df, "Category", c(2, 3, 4, 5, 2))
# Sample 15% from each group
strata.sampling(df, "Category", .15)

我在這里一個增強的功能。 該函數可以優雅地處理組可能具有比指定數量的樣本更少的觀察值的情況,並且還允許您按多個變量進行分層。 有關幾個示例,請參閱文檔

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM