取这个样本数据
df <- structure(list(t = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L,
11L, 12L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L),
id = c(10010L, 10010L, 10010L, 10010L, 10010L, 10010L, 10010L,
10010L, 10010L, 10010L, 10010L, 10010L, 10020L, 10020L, 10020L,
10020L, 10020L, 10020L, 10020L, 10020L, 10020L, 10020L, 10020L,
10020L), asset = c(45145L, 45145L, 45145L, 96730L, 96730L,
96730L, 145511L, 145511L, 145511L, 190986L, 190986L, 190986L,
20050L, 20050L, 20050L, 50411L, 50411L, 50411L, 120154L,
120154L, 120154L, 173575L, 173575L, 173575L)), class = "data.frame", row.names = c(NA,
-24L))
> df
t id asset
1 1 10010 45145
2 2 10010 45145
3 3 10010 45145
4 4 10010 96730
5 5 10010 96730
6 6 10010 96730
7 7 10010 145511
8 8 10010 145511
9 9 10010 145511
10 10 10010 190986
11 11 10010 190986
12 12 10010 190986
13 1 10020 20050
14 2 10020 20050
15 3 10020 20050
16 4 10020 50411
17 5 10020 50411
18 6 10020 50411
19 7 10020 120154
20 8 10020 120154
21 9 10020 120154
22 10 10020 173575
23 11 10020 173575
24 12 10020 173575
Approach-1 Base R 方法
- 首先
the additions during the year
使用ave()
基础 R 计算。实际上,您的资产价值列就像资产的累积值,它必须像当月的增加一样减少。(步骤1)
- 为了应用您的迭代逻辑,我建议使用
Reduce()
带有 agrument的 baseR 函数accumulate = TRUE
。这将有助于生成您的残值列。(第 2 步)
- 此后,生成折旧值列。这将是累积折旧。因此,仅将其减少到每月折旧。(第 3 步)
- 您可以删除最后在步骤1中生成的列(这是可选的)
#1 calculation of asset_addition column
df$asset_addition <- with(df, ave(asset, id, FUN = function(x){c(x[1], diff(x))}))
#2 desired iteration
df$end_res <- with(df,
ave(replace(asset_addition,
t==1,
asset_addition[t==1]*11.8/12),
id,
FUN = function(z){Reduce(function(x, y){(x+y)*11.8/12},
z,
accumulate = T)}))
#3 depr. column calculation
df$depr. <- with(df, ave(asset - end_res, id, FUN = function(x){c(x[1], diff(x))}))
检查结果
df
t id asset asset_addition end_res depr.
1 1 10010 45145 45145 44392.58 752.4167
2 2 10010 45145 0 43652.71 739.8764
3 3 10010 45145 0 42925.16 727.5451
4 4 10010 96730 51585 92934.99 1575.1694
5 5 10010 96730 0 91386.08 1548.9165
6 6 10010 96730 0 89862.97 1523.1013
7 7 10010 145511 48781 136333.24 2310.7329
8 8 10010 145511 0 134061.02 2272.2207
9 9 10010 145511 0 131826.67 2234.3504
10 10 10010 190986 45475 174346.64 2955.0278
11 11 10010 190986 0 171440.87 2905.7774
12 12 10010 190986 0 168583.52 2857.3478
13 1 10020 20050 20050 19715.83 334.1667
14 2 10020 20050 0 19387.24 328.5972
15 3 10020 20050 0 19064.12 323.1206
16 4 10020 50411 30361 48601.36 823.7519
17 5 10020 50411 0 47791.34 810.0227
18 6 10020 50411 0 46994.82 796.5223
19 7 10020 120154 69743 114792.19 1945.6303
20 8 10020 120154 0 112878.99 1913.2031
21 9 10020 120154 0 110997.67 1881.3164
22 10 10020 173575 53421 161678.36 2740.3111
23 11 10020 173575 0 158983.72 2694.6393
24 12 10020 173575 0 156333.99 2649.7286
方法 2 dplyr
方法。
- 这是一种略有不同的方法。生成累积折旧百分比并将其用于生成剩余列。但是,任何资产的价值,如果有的话,在这一年中,都会提前计算。
library(dplyr)
df %>% group_by(id) %>%
mutate(end_value = cumsum((asset - lag(asset, default = 0))/((1-.2/12)^(t-1))) * (1-.2/12)^t,
depr. = asset - end_value,
depr. = c(depr.[1], diff(depr.)))
# A tibble: 24 x 5
# Groups: id [2]
t id asset end_value depr.
<int> <int> <int> <dbl> <dbl>
1 1 10010 45145 44393. 752.
2 2 10010 45145 43653. 740.
3 3 10010 45145 42925. 728.
4 4 10010 96730 92935. 1575.
5 5 10010 96730 91386. 1549.
6 6 10010 96730 89863. 1523.
7 7 10010 145511 136333. 2311.
8 8 10010 145511 134061. 2272.
9 9 10010 145511 131827. 2234.
10 10 10010 190986 174347. 2955.
# ... with 14 more rows
这与您想要的输出完全相同
方法 3使用purrr::accumulate()
#approach-3 similar to approach-1 but using dplyr verbs & purrr::accumulate in one single pipe
library(tidyverse)
df %>% group_by(id) %>%
mutate(asset_add = c(0, diff(asset)),
end_res = accumulate(asset_add, ~ (.x + .y)*(11.8/12), .init = asset[1])[-1],
depr. = asset - end_res,
depr. = c(depr.[1], diff(depr.))) %>%
ungroup() %>%
select(-asset_add)
# A tibble: 24 x 5
t id asset end_res depr.
<int> <int> <int> <dbl> <dbl>
1 1 10010 45145 44393. 752.
2 2 10010 45145 43653. 740.
3 3 10010 45145 42925. 728.
4 4 10010 96730 92935. 1575.
5 5 10010 96730 91386. 1549.
6 6 10010 96730 89863. 1523.
7 7 10010 145511 136333. 2311.
8 8 10010 145511 134061. 2272.
9 9 10010 145511 131827. 2234.
10 10 10010 190986 174347. 2955.
# ... with 14 more rows