调整组内的一组值,使其总和为100

时间:2019-06-20 18:03:55

标签: r dplyr aggregate

在软件平台上进行数据验证时,坚持每个人的分配必须是正好等于100的整数。假设一个人在三个项目中的分配比例为33-33-33,其中一个应在提交之前调整为34被接受。如果是25-76,则应将其中之一向下调1。无论哪个被调整。

以下是示例数据:

dat <- data.frame(person = c(1, 1, 1, 2, 2, 2),
                  proj = c("a", "b", "c", "a", "d", "e"),
                  alloc = c(40, 50, 11, 33, 33, 33))

dat
  person proj alloc
1      1    a    40
2      1    b    50
3      1    c    11
4      2    a    33
5      2    d    33
6      2    e    33

在此示例中,正确的dat$alloc调整值包括39, 50, 11, 34, 33, 3340, 50, 10, 33, 33, 34等。

什么是干净,简单的方法?现在,我正在创建一个新的data.frame来计算调整,然后使用虚拟行ID变量等将其重新加入。我宁愿只在dplyr group_by操作中进行操作,并避免创建一个单独的data.frame。

2 个答案:

答案 0 :(得分:1)

例如,您可以将其中一个值替换为100与另一个值之和之间的差

dat %>% 
  group_by(person) %>% 
  mutate(alloc=c(100-sum(alloc[-1]), alloc[-1]))

在这里,我们用alloc[1]替换第一个值100-sum(alloc[-1]),并保留所有其他值。

答案 1 :(得分:1)

轻微的变化将四舍五入分配给最大的数字:

library(dplyr)
dat2 <- dat %>%
  group_by(person) %>%
  arrange(person, -alloc, proj)) %>%
  mutate(alloc = alloc + if_else(row_number() == 1, 100 - sum(alloc), 0))