随机分组每个组以满足条件

时间:2017-02-06 18:23:08

标签: r for-loop while-loop dplyr

希望通过循环遍历每个资源的名称来减少资源分配,并查看分配给该人名的帐户,随机选择一个并用NA替换该人的姓名。

可重复的例子:

Accts <- paste0("Acc", 1:200)
Value <- c(500, 2000, 5000, 1000)
AccountDF <- data.frame(Accts, Value)
AccountDF$Owner[1:200] <- NA
AccountDF$Owner[1:23] <- "Jeff"
AccountDF$Owner[24:37] <- "Alex"
AccountDF$Owner[38:61] <- "Steph"
AccountDF$Owner[62:111] <- "Matt"
AccountDF$Owner[112:141] <- "David"

library(dplyr)
OwnerDF <- AccountDF %>%
  group_by(Owner) %>%
  summarise(Count = n(),
            TotalValue = sum(Value)) %>%
  filter(!is.na(Owner))

我到目前为止的地方:

for (p in 1:nrow(OwnerDF)){
  while (AccountDF$Count[p] > 22){
    AccountDF %>%
      filter(Owner == OwnerDF$Owner[p]) %>%
      sample_n(1)


  }
}

我听说for循环是不必要的。我确定可以使用purr包和pmap或类似的东西来完成。我仍在学习。

我想遍历OwnerDF并查看该人是否拥有&#34;帐户太多了。如果是,请查看原始帐户列表并选择一个随机帐户,并将所有者的名称替换为NA,从其计数中删除1,然后继续。

最后在搞清楚之后我想看看它是否可以用多个条件完成..比如While(Count&gt; 22&amp; Value&gt; $ 40,000),或者两个while循环。目标是减少每个人拥有的&#34;帐户小于某个阈值并将$$减少到小于某个阈值。

1 个答案:

答案 0 :(得分:1)

要选择随机帐户,只需创建一个随机变量并对其进行排序,获取符合条件的前N个帐户:

 set.seed(1)
 res = AccountDF %>% 
   mutate(r = runif(n())) %>% 
   arrange(r) %>% 
   group_by(Owner) %>% 
   mutate(newOwner = replace(Owner, cumsum(Value) > 40000 | row_number() > 22, NA)) %>% 
   select(-r)

# Test that it worked...
res %>%
  filter(!is.na(newOwner)) %>%
  group_by(newOwner) %>%
  summarise(Count = n(), TotalValue = sum(Value))

# A tibble: 5 x 3
#   newOwner Count TotalValue
#      <chr> <int>      <dbl>
# 1     Alex    14      27000
# 2    David    18      37000
# 3     Jeff    18      39500
# 4     Matt    18      39500
# 5    Steph    17      36500

OP在评论中提到的扩展名:

  

另一个问题。假设我有一个每个值和计数的阈值,如果某人的数量很少但价值很高,我想从他们的高价值账户中取一个随机账户,如果他们有高计数和低价值,我想要低价值账户远离他们。我如何从随机的角度来做这件事?

我可能会为每个观察分配一个真值得分,比如......

s = scale(f(x))

其中f是基于您提到的条件(高计数,高值或两者)的某些函数,当您想要偏向低值{{1}时,可能就像x一样简单当你想偏向高价值时。

然后,使用上面的结果添加一些噪音并排序:

-x