是否有任何方法可以创建一个变量,这取决于它在R中的早期观察?
在下面的例子中,"资产"一栏应按每个时间段(t)折旧1.67% (20%/12)
第一个'end result' = 'asset - depr'
我面临的问题是,从第2行开始,'end-result'中的值必须依赖于前一个时间段的'end-result'。
从t=2开始,深度。为'end-result, t-1' * 1,67%
谢谢!
(这是最终产品应该看起来的样子)-也按PERMNO (ID)排序
t id asset depr. end_result
1 10010 45145 752 44393
2 10010 45145 740 43653
3 10010 45145 728 42925
4 10010 96730 1575 92935
5 10010 96730 1549 91386
6 10010 96730 1523 89863
7 10010 145511 2311 136333
8 10010 145511 2272 134061
9 10010 145511 2234 131827
10 10010 190986 2955 174347
11 10010 190986 2906 171441
12 10010 190986 2857 168584
1 10020 20050 334 19716
2 10020 20050 329 19387
3 10020 20050 323 19064
4 10020 50411 824 48601
5 10020 50411 810 47791
6 10020 50411 797 46995
7 10020 120154 1946 114792
8 10020 120154 1913 112879
9 10020 120154 1881 110998
10 10020 173575 2740 161678
11 10020 173575 2695 158984
12 10020 173575 2650 156334
取此示例数据
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
方法1基数R法
- 首先用r为基数的
ave()
来计算the additions during the year
。实际上,您的资产价值列就像资产的累积价值,它必须在一个月内像只增加一样减少。(步骤1) - 为了应用你的迭代逻辑,我建议使用基础函数
Reduce()
和协议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
方法2dplyr
方法。
- 这是一个稍微不同的方法。生成累计折旧百分比,并将其用于生成剩余列。但是,年内增加的任何资产价值(如果有的话)将提前计算。
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