楼主: wsnmgp
1363 3

[问答] R 语言 随机抽样 [推广有奖]

  • 0关注
  • 0粉丝

大专生

61%

还不是VIP/贵宾

-

威望
0
论坛币
445 个
通用积分
0.9052
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
53 点
帖子
4
精华
0
在线时间
109 小时
注册时间
2018-5-9
最后登录
2023-3-5

楼主
wsnmgp 发表于 2020-5-19 22:19:27 |AI写论文
500论坛币
比如说我的数据框是这样的

x1 x2 x3 x4 x5
1  0   3   0   4
2  1   1   0   8
2  2   1   1   2
4  1   1   9   11

以上的求和是54,我知道sample函数是随机取的【个数】一定,但是如果我需要 随机抽出的样本 是【总和】一定呢?
比如随机抽样一次,随机取的数量(size) 无所谓,但是保证最后形成的新数据框 求和是30
比如变成这样

x1  x2  x4  x5
1   2    3    8
2   2    1   11
求和为30

关键词:随机抽样 Sample size AMPL 数据框

沙发
crystal8832 学生认证  发表于 2020-5-20 09:08:43
我能想到的就是通过遍历的方式随机识别,不过这样效率好低呀。应该还有别的办法...

藤椅
龙熏风 发表于 2020-5-20 18:40:07
个人感觉你的这个已经不能叫随机抽样了
写了一个小程序,应该还可以优化,供君参考
  1. sampleProcess <- function(series, value, items = c()) {

  2.     if (value == sum(series)) return(c(items, series))
  3.    
  4.     selTemp <- series == value
  5.     if (sum(selTemp) == 1 & length(items) > 0) {
  6.         return(c(items, series[selTemp]))
  7.     }

  8.     #drop the items larger than value
  9.     series <- series[which(series < value)]
  10.     if (length(series) == 0) return(items)


  11.     #find the cup (minimal set number)
  12.     series <- sort(series, decreasing = TRUE)
  13.     sum.array <- sapply(seq(length(series)),
  14.         function(i, series) sum(series[1:i]), series = series)
  15.     cup <- which(sum.array >= value)[1]
  16.    
  17.     #sample
  18.     index <- seq(length(series))
  19.     selTemp <- index %in% sample(index, cup)
  20.     itemsTemp <- series[selTemp]
  21.     sumTemp <- sum(itemsTemp)
  22.     if (sumTemp == value) {
  23.         return(c(items, itemsTemp))
  24.     } else if (sumTemp < value) {
  25.         series <- series[!selTemp]
  26.         items <- c(items, itemsTemp)
  27.         value <- value - sumTemp
  28.         return(sampleProcess(series, value, items = items))
  29.     } else {
  30.         return(sampleProcess(series, value, items = items))
  31.     }
  32. }

  33. sampleBySum <- function(series, value, iter) {
  34.     if (value > sum(series)) stop("the sum of series if below value")
  35.    
  36.     #drop the items larger than value
  37.     series <- series[which(series <= value)]
  38.     if (length(series) == 0) stop("no item below value")

  39.     i <- 1
  40.     while (i <= iter) {
  41.         items <- sampleProcess(series, value)
  42.         if (sum(items) == value) {
  43.             cat("iter = ", i, "\n")
  44.             break
  45.         }
  46.         i <- i + 1
  47.     }

  48.     if (sum(items) != value) warning("no finds")
  49.     return(items)

  50. }

  51. x <- c(1,0,3,0,4,2,1,1,0,8,2,2,1,1,2,4,1,1,9,11)

  52. sampleBySum(x, 30, 10)
复制代码

板凳
llb_321 在职认证  发表于 2020-5-20 18:43:05
d <-
  matrix(c(1, 2, 2, 4, 0, 1, 2, 1, 3, 1, 1, 1, 0, 0, 1, 9, 4, 8, 2, 11), 4)
k = 1
repeat {
  i <- sample(1:(dim(d)[1]), 1)
  a <- matrix(0, dim(d)[1], dim(d)[2])
  for (j in 1:dim(d)[2]) {
    a[, j] <- c(sample(d[, j], i), rep(0, dim(d)[1] - i))
    if (sum(a) == 30) {
      print(a)
      break
    }
  }
  if (k > 10000)
    break
  k <- k + 1
}
结果有很多很多,当然没想办法识别重复结果,所以设了k作终止条件。你试试吧。
另外,不要你的币,我的币已经够多的了。就是玩。

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2026-1-16 15:53