R 是否创建计算两列的函数,并从第一列开始计算第二列?
我试图在data.table中执行以下操作,或者创建一个函数来替换for循环。但是,我不知道如何返回两列,其中一列取决于另一列的计算。数据集按月包含每个“地点”的销售和交付单位,但仅包含第一个月的起始库存。我需要通过首先计算上个月在该地点的期末库存来计算每个期间的期初库存。每个地方的期末存货等于起始存货减去销售单位加上交货单位 以下是我目前的计算方法:R 是否创建计算两列的函数,并从第一列开始计算第二列?,r,R,我试图在data.table中执行以下操作,或者创建一个函数来替换for循环。但是,我不知道如何返回两列,其中一列取决于另一列的计算。数据集按月包含每个“地点”的销售和交付单位,但仅包含第一个月的起始库存。我需要通过首先计算上个月在该地点的期末库存来计算每个期间的期初库存。每个地方的期末存货等于起始存货减去销售单位加上交货单位 以下是我目前的计算方法: data <- data.table(place = c('a','b'), month = c(1,1
data <- data.table(place = c('a','b'),
month = c(1,1,2,2,3,3,4,4,5,5,6,6),
sales = c(20,2,3,5,6,7,8,1,5,1,5,3),
delivery = c(1,1,1,1,1,1,1,1,1,1,1,1),
starting_inv = c(100,100,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA),
ending_inv = c(81,99,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA) )
print(data)
place month sales delivery starting_inv ending_inv
1: a 1 20 1 100 81
2: b 1 2 1 100 99
3: a 2 3 1 NA NA
4: b 2 5 1 NA NA
5: a 3 6 1 NA NA
6: b 3 7 1 NA NA
7: a 4 8 1 NA NA
8: b 4 1 1 NA NA
9: a 5 5 1 NA NA
10: b 5 1 1 NA NA
11: a 6 5 1 NA NA
12: b 6 3 1 NA NA
dt <- data[order(place,month)]
print(dt)
place month sales delivery starting_inv ending_inv
1: a 1 20 1 100 81
2: a 2 3 1 NA NA
3: a 3 6 1 NA NA
4: a 4 8 1 NA NA
5: a 5 5 1 NA NA
6: a 6 5 1 NA NA
7: b 1 2 1 100 99
8: b 2 5 1 NA NA
9: b 3 7 1 NA NA
10: b 4 1 1 NA NA
11: b 5 1 1 NA NA
12: b 6 3 1 NA NA
for (i in 1:nrow(dt)) {
if (dt[i]$month != 1) {
dt$starting_inv[i] <- dt[i-1]$ending_inv
dt$ending_inv[i] <- dt[i]$starting_inv - dt[i]$sales + dt[i]$delivery
}
}
print(dt)
place month sales delivery starting_inv ending_inv
1: a 1 20 1 100 81
2: a 2 3 1 81 79
3: a 3 6 1 79 74
4: a 4 8 1 74 67
5: a 5 5 1 67 63
6: a 6 5 1 63 59
7: b 1 2 1 100 99
8: b 2 5 1 99 95
9: b 3 7 1 95 89
10: b 4 1 1 89 89
11: b 5 1 1 89 89
12: b 6 3 1 89 87
data迭代由累积和捕获,其余的可以矢量化,因此应该很快
data[, starting_inv := cumsum(shift(delivery-sales, fill = starting_inv[1])), place]
data[, ending_inv := starting_inv+delivery-sales]
data
#> place month sales delivery starting_inv ending_inv
#> 1: a 1 20 1 100 81
#> 2: b 1 2 1 100 99
#> 3: a 2 3 1 81 79
#> 4: b 2 5 1 99 95
#> 5: a 3 6 1 79 74
#> 6: b 3 7 1 95 89
#> 7: a 4 8 1 74 67
#> 8: b 4 1 1 89 89
#> 9: a 5 5 1 67 63
#> 10: b 5 1 1 89 89
#> 11: a 6 5 1 63 59
#> 12: b 6 3 1 89 87
这假设您正在处理的实际数据是按月份排序的。如果不是,则在第一行的第一个方括号后插入一个订单(月)
。这里有一个选项带有累加2
frompurr
library(purrr)
library(dplyr)
library(tidyr)
dt %>%
group_by(place) %>%
dplyr::mutate(starting_inv = accumulate2(delivery, sales,
~ ..1 - ..3 + ..2 , .init = first(starting_inv))[-n()]) %>%
unnest(c(starting_inv)) %>%
mutate(ending_inv = lead(starting_inv))
# A tibble: 12 x 6
# Groups: place [2]
# place month sales delivery starting_inv ending_inv
# <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 a 1 20 1 100 81
# 2 a 2 3 1 81 79
# 3 a 3 6 1 79 74
# 4 a 4 8 1 74 67
# 5 a 5 5 1 67 59
# 6 a 6 5 1 59 NA
# 7 b 1 2 1 100 99
# 8 b 2 5 1 99 95
# 9 b 3 7 1 95 89
#10 b 4 1 1 89 89
#11 b 5 1 1 89 87
#12 b 6 3 1 87 NA
dt[, starting_inv := unlist(accumulate2(delivery, sales,
function(x, y, z) x - z + y ,
.init = first(starting_inv))[-.N]), place][, ending_inv :=
shift(starting_inv, type = 'lead'), place]