R - 使用 dplyr mutate 分配总数的一部分

R - using dplyr mutate to allocate a proportion of a total number

我有一组为不同邮政编码区域提供服务的 5G 移动基础设施成本数据:

observation <- c(1:10)
pop.d.rank  <- c(1:10)
cost  <- c(101:110)
all <- data.frame(observation,pop.d.rank,cost) 

然后我想看看,每年一定的投入,一定的可用资金能覆盖多少人。假设 annual.investment 如下:

annual.investment <- 500

下面我使用 dplyr 尝试根据成本变量将此 annual.investment 分配给数据中的不同地理类型区域:

all <- all %>% group_by(pop.d.rank) %>% 
       mutate(capital_allocated.5G = diff(c(0, pmin(cumsum(cost), annual.investment)))) %>%
       mutate(capital_percentage.5G = capital_allocated.5G / cost * 100)

但是,这里的问题是每次都将 annual.investment 数量的 500 分配给数据中的每个观察值,而不是所有观察值的总量。关于如何更改此代码以执行此操作的任何建议?

数据之后应该是这样的:

observation <- c(1:10)
pop.d.rank  <- c(1:10)
cost  <- c(101:110)
capital_allocated.5G <- c(101, 102, 103, 104, 90, 0, 0, 0, 0, 0)
capital_percentage.5G <- c(100, 100, 100, 100, 86, 0, 0, 0, 0, 0)
example.output <- data.frame(observation,pop.d.rank,cost, capital_allocated.5G, capital_percentage.5G) 

您可以使用 transform

all <- transform(all, 
          capital_allocated.5G = diff(c(0, pmin(cumsum(cost), annual.investment))))
all <- transform(all,
                 capital_percentage.5G = capital_allocated.5G / cost * 100)

或者为了避免重复您的代码,您可以这样做:

all <- with(all,{
    capital_allocated.5G = diff(c(0, pmin(cumsum(cost), annual.investment)))
    capital_percentage.5G = capital_allocated.5G / cost * 100
    return(cbind(all, capital_allocated.5G,
                 capital_percentage.5G))
})

它们都给你相同的输出:

##   observation pop.d.rank cost capital_allocated.5G capital_percentage.5G
## 1            1          1  101                  101             100.00000
## 2            2          2  102                  102             100.00000
## 3            3          3  103                  103             100.00000
## 4            4          4  104                  104             100.00000
## 5            5          5  105                   90              85.71429
## 6            6          6  106                    0               0.00000
## 7            7          7  107                    0               0.00000
## 8            8          8  108                    0               0.00000
## 9            9          9  109                    0               0.00000
## 10          10         10  110                    0               0.00000

此外,如果您删除 group_by(pop.d.rank)

,您的代码将完全正常工作