在下面的数据中,我们观察了一个特定国家随时间的指数化GDP增长率。我的目标是创建一个二元变量:0=没有危机,1=危机。如果该指数低于过去5年平均水平,则该变量被编码为1=危机,直到它回到最初的5年平均水平。
在下面的例子中,1990年至1994年的GDP平均值是98。1995年,GDP为96,因此变量编码为1,直到1999年上升到99(超过98的水平)。这种情况在2002年至2005年间再次发生,直到GDP水平回到1997年至2001年的5年平均水平101.6以上。有人能帮帮忙吗?
GDP year Expected output
100 1990 0
99 1991 0
98 1992 0
97 1993 0
98 1994 0
96 1995 1
94 1996 1
95 1997 1
97 1998 1
99 1999 0
110 2000 0
107 2001 0
100 2002 1
98 2003 1
99 2004 1
97 2005 1
102 2006 0
103 2007 0
102 2008 0
数据如下:
df= structure(list(`Index 100` = c(100, 99, 98, 97, 98, 96, 94, 95,
97, 99, 110, 107, 100, 98, 99, 97, 102, 103, 102), year = c(1990,
1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006, 2007, 2008), `Expected output` = c(0,
0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0)), row.names = c(NA,
-19L), class = "data.frame")
您可以使用滑块的slide_dbl
来获得以下前5年的mean
:
注意事项:
- 如果没有
.complete = TRUE
,它将计算部分窗口的平均值。 - 如果你的真实数据集有多个国家,那么不要忘记先
group_by(country) |>
。 - 你可以考虑使用janitor的
clean_names
来确保变量名是符合语法的,例如不需要反引号。
library(tidyverse)
library(slider)
# Sample data
df <- structure(list(`Index 100` = c(
100, 99, 98, 97, 98, 96, 94, 95,
97, 99, 110, 107, 100, 98, 99, 97, 102, 103, 102
), year = c(
1990,
1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006, 2007, 2008
), `Expected output` = c(
0,
0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0
)), row.names = c(
NA,
-19L
), class = "data.frame")
# Code
df |>
arrange(year) |>
mutate(
sliding_mean = slide_dbl(lag(`Index 100`), mean, .before = 4, .complete = TRUE),
crisis = case_when(
`Index 100` < sliding_mean ~ 1,
`Index 100` >= sliding_mean & `Index 100` < first(na.omit(sliding_mean)) ~ 1,
TRUE ~ 0
)
)
#> Index 100 year Expected output sliding_mean crisis
#> 1 100 1990 0 NA 0
#> 2 99 1991 0 NA 0
#> 3 98 1992 0 NA 0
#> 4 97 1993 0 NA 0
#> 5 98 1994 0 NA 0
#> 6 96 1995 1 98.4 1
#> 7 94 1996 1 97.6 1
#> 8 95 1997 1 96.6 1
#> 9 97 1998 1 96.0 1
#> 10 99 1999 0 96.0 0
#> 11 110 2000 0 96.2 0
#> 12 107 2001 0 99.0 0
#> 13 100 2002 1 101.6 1
#> 14 98 2003 1 102.6 1
#> 15 99 2004 1 102.8 1
#> 16 97 2005 1 102.8 1
#> 17 102 2006 0 100.2 0
#> 18 103 2007 0 99.2 0
#> 19 102 2008 0 99.8 0
# Check
(100+99+98+97+98)/5
#> [1] 98.4
由reprex包(v2.0.1)创建于2022-07-28
试试这个
library(dplyr)
df |> mutate(crisis = case_when(lag(c( rep(0 , 4),
zoo::rollmean(df$GDP , 5)),1)> GDP ~ 1 , TRUE ~ 0))
输出GDP year crisis
1 100 1990 0
2 99 1991 0
3 98 1992 0
4 97 1993 0
5 98 1994 0
6 96 1995 1
7 94 1996 1
8 95 1997 1
9 97 1998 0
10 99 1999 0
11 110 2000 0
12 107 2001 0
13 100 2002 1
14 98 2003 1
15 99 2004 1
16 97 2005 1
17 102 2006 0
18 103 2007 0
19 102 2008 0
- 输出以提高对解决方案的理解
GDP year crisis Five_years_avg
1 100 1990 0 NA
2 99 1991 0 0.0
3 98 1992 0 0.0
4 97 1993 0 0.0
5 98 1994 0 0.0
6 96 1995 1 98.4
7 94 1996 1 97.6
8 95 1997 1 96.6
9 97 1998 0 96.0
10 99 1999 0 96.0
11 110 2000 0 96.2
12 107 2001 0 99.0
13 100 2002 1 101.6
14 98 2003 1 102.6
15 99 2004 1 102.8
16 97 2005 1 102.8
17 102 2006 0 100.2
18 103 2007 0 99.2
19 102 2008 0 99.8
1998年的GDP是97,过去5年的平均值是96,所以没有危机。