I have a dataset with three columns country, years, and growth. I want to identify periods when a country experienced >=6% growth for 3 or more years, alongside another column with the mean growth during that period.
I need to create a data frame like: Albania 1999-2001, 0.133 (namely country, period, and mean_growth columns), etc.
I filtered the original data frame to show the years where growth was >= 0.06. Here's one country:
country cow_code years growth
1 Albania 339 1999 0.158
2 Albania 339 2000 0.106
3 Albania 339 2001 0.136
4 Albania 339 2003 0.123
5 Albania 339 2004 0.0930
6 Albania 339 2006 0.228
7 Albania 339 2007 0.238
8 Albania 339 2008 0.178
9 Albania 339 2010 0.0744
10 Albania 339 2018 0.0825
11 Albania 339 2019 0.137
12 Albania 339 2021 0.181
I want to produce something like this for all the countries that are in my original dataframe:
country period mean_growth
1 Albania 1999-2001 0.133
2 Albania 2006-2008 0.215
Any clue how I can do this?
You can use cumsum(c(1, diff(years) != 1)) to split the data into the groups of consecutive years by countries.
library(dplyr)
df %>%
mutate(grp = cumsum(c(1, diff(years) != 1)), .by = country) %>%
group_by(country, grp) %>%
filter(n() >= 3) %>%
summarise(period = paste(range(years), collapse = '-'),
mean_growth = mean(growth), .groups = "drop") %>%
select(-grp)
# # A tibble: 2 × 3
# country period mean_growth
# <chr> <chr> <dbl>
# 1 Albania 1999-2001 0.133
# 2 Albania 2006-2008 0.215
Data
df <- read.table(text = "
country cow_code years growth
1 Albania 339 1999 0.158
2 Albania 339 2000 0.106
3 Albania 339 2001 0.136
4 Albania 339 2003 0.123
5 Albania 339 2004 0.0930
6 Albania 339 2006 0.228
7 Albania 339 2007 0.238
8 Albania 339 2008 0.178
9 Albania 339 2010 0.0744
10 Albania 339 2018 0.0825
11 Albania 339 2019 0.137
12 Albania 339 2021 0.181")
Here's a data.table approach:
library(data.table)
setDT(df1)[growth >= 0.06,][order(country, years),
consec := cumsum(c(TRUE, diff(as.numeric(years)) > 1)),
.(country)][, if (.N > 2) .SD,
.(country, consec)][,.(period = paste(first(years),
last(years),
sep = "-"),
avg_growth = mean(growth)),
.(country, consec)][, !"consec"]
#> country period avg_growth
#> 1: Albania 1999-2001 0.1333333
#> 2: Albania 2006-2008 0.2146667
It's better if we arrange based on years first before identifying consecutive years. Here's a dplyr solution with that step added.
library(dplyr)
df1 %>%
filter(growth >= 0.06) %>%
arrange(country, years) %>%
mutate(consec = cumsum(c(TRUE, diff(as.numeric(years)) > 1)),
.by = country) %>%
group_by(country, consec) %>%
filter(n() >= 3) %>%
summarise(years = paste(years[1],years[n()], sep = "-"),
avg_growth = mean(growth),
.groups = "drop") %>%
select(-consec)
#> # A tibble: 2 x 3
#> country years avg_growth
#> <chr> <chr> <dbl>
#> 1 Albania 1999-2001 0.133
#> 2 Albania 2006-2008 0.215
Data:
read.table(text = " country cow_code years growth
1 Albania 339 1999 0.158
2 Albania 339 2000 0.106
3 Albania 339 2001 0.136
4 Albania 339 2003 0.123
5 Albania 339 2004 0.0930
6 Albania 339 2006 0.228
7 Albania 339 2007 0.238
8 Albania 339 2008 0.178
9 Albania 339 2010 0.0744
10 Albania 339 2018 0.0825
11 Albania 339 2019 0.137
12 Albania 339 2021 0.181" , header = T, stringsAsFactors = F) -> df1
Related
So I have two dataframes, "df1" and "df2" (see code below). I want to create a new variable in "df1" by iterating trough the elDate variable in "df2", and picking the closest elDate value above the date value in "df1".
For example, the first row in "df1" is Albania with the date 1996-12-24. I want the value in the new variable to be 1997-06-29, which is the closest elDate in "df2" above date in "df1".
The main thing is to stop at the first elDate which is above date.
library(tidyverse)
library(lubridate)
df1 <- tibble(country = c(rep("Albania", 11), rep("Algeria", 7)),
date = ymd("1996-12-24", "1997-01-30", "2009-07-30", "2011-07-08", "2012-04-18", "2012-01-20", "2013-05-16", "2016-03-03", "2017-05-11", "2018-09-07", "2022-05-31", "2005-01-10", "2006-07-12", "2012-10-09", "2012-11-15", "2014-04-18", "2017-06-07", "2017-01-24"))
df2 <- tibble(country = c(rep("Albania", 9), rep("Algeria", 6)),
elDate = ymd("2025-04-25", "2021-04-25", "2017-06-25", "2013-06-25", "2009-06-28", "2005-07-03", "2001-07-08", "1997-06-29", "1996-05-26", "2021-06-12", "2017-05-04", "2012-05-10", "2007-05-17", "2007-05-30", "2002-05-30"))
I want the new dataframe to look like this:
country
date
elDate
Albania
24-12-1996
29-06-1997
Albania
30-01-1997
29-06-1997
Albania
30-07-2009
25-06-2013
Albania
08-07-2011
25-06-2013
Albania
18-04-2012
25-06-2013
Albania
20-01-2012
25-06-2013
Albania
16-05-2013
25-06-2013
Albania
03-03-2016
25-06-2017
Albania
11-05-2017
25-06-2017
Albania
07-09-2018
25-04-2021
Albania
31-05-2022
24-04-2025
Algeria
10-01-2005
30-05-2007
Algeria
12-07-2006
30-05-2007
Algeria
09-10-2012
04-05-2017
Algeria
15-11-2012
04-05-2017
Algeria
18-04-2014
04-05-2017
Algeria
07-06-2017
12-06-2021
Algeria
24-01-2017
12-06-2021
Algeria
07-06-2017
12-06-2021
Suggestions are much appreciated!
Thanks!
You can try inequality joins in dplyr:
library(dplyr) #1.1.0 and above
df1 %>%
left_join(df2, by = join_by(country, closest(date <= elDate)))
# A tibble: 18 × 3
country date elDate
<chr> <date> <date>
1 Albania 1996-12-24 1997-06-29
2 Albania 1997-01-30 1997-06-29
3 Albania 2009-07-30 2013-06-25
4 Albania 2011-07-08 2013-06-25
5 Albania 2012-04-18 2013-06-25
6 Albania 2012-01-20 2013-06-25
7 Albania 2013-05-16 2013-06-25
8 Albania 2016-03-03 2017-06-25
9 Albania 2017-05-11 2017-06-25
10 Albania 2018-09-07 2021-04-25
11 Albania 2022-05-31 2025-04-25
12 Algeria 2005-01-10 2007-05-17
13 Algeria 2006-07-12 2007-05-17
14 Algeria 2012-10-09 2017-05-04
15 Algeria 2012-11-15 2017-05-04
16 Algeria 2014-04-18 2017-05-04
17 Algeria 2017-06-07 2021-06-12
18 Algeria 2017-01-24 2017-05-04
I have a dataset covering 1945-2021 and census values for every tenth year (simplified below) and I am currently trying to use tidyr::fill to fill each census value for the five years before and after the census was taken (e.g. the 1991 census should apply to 1986 - 1995). However, my code takes the first census values and fills up and down to the next census value, which only fills down and so on.
dat_filled <- dat %>%
fill(value, .direction = "downup")
Original data
#> year value
#> 1945 <NA>
#> 1946 A
#> 1947 <NA>
#> 1948 <NA>
#> 1949 <NA>
#> 1950 <NA>
#> 1951 <NA>
#> 1952 <NA>
#> 1953 <NA>
#> 1954 <NA>
#> 1955 <NA>
#> 1956 B
#> 1957 <NA>
#> 1958 <NA>
#> 1959 <NA>
#> 1960 <NA>
#> 1961 <NA>
#> 1962 C
#> 1963 <NA>
#> 1964 <NA>
What I currently get (first value, A, goes all the way down to the first occurrence of B, and then same for C)
#> year value
#> 1945 A
#> 1946 A
#> 1947 A
#> 1948 A
#> 1949 A
#> 1950 A
#> 1951 A
#> 1952 A
#> 1953 A
#> 1954 A
#> 1955 A
#> 1956 B
#> 1957 B
#> 1958 B
#> 1959 B
#> 1960 B
#> 1961 B
#> 1962 C
#> 1963 C
#> 1964 C
What I want (A does one 'updown', then B, then C, and then repeat until all NAs are filled)
#> year value
#> 1945 A
#> 1946 A
#> 1947 A
#> 1948 A
#> 1949 A
#> 1950 A
#> 1951 A
#> 1952 B
#> 1953 B
#> 1954 B
#> 1955 B
#> 1956 B
#> 1957 B
#> 1958 B
#> 1959 B
#> 1960 C
#> 1961 C
#> 1962 C
#> 1963 C
#> 1964 C
My actual data is slightly more complicated than this, but only due to one group_by function.
One way you could do this is using join:
df %>%
filter(!is.na(value)) %>%
mutate(year = map(year, ~seq(.x-5, .x+4)))%>%
unnest(year) %>%
right_join(df[1])
year value
1 1945 A
2 1946 A
3 1947 A
4 1948 A
5 1949 A
6 1950 A
7 1951 B
8 1952 B
9 1953 B
10 1954 B
11 1955 B
12 1956 B
13 1957 B
14 1958 B
15 1959 B
16 1960 B
17 1957 C
18 1958 C
19 1959 C
20 1960 C
21 1961 C
22 1962 C
23 1963 C
24 1964 C
I have searched through the forums and have not found exactly the answer to my question. I have a data set from the World Bank
library(wbstats)
Gini <- wb(indicator = c("SI.POV.GINI"),
startdate = 2005, enddate = 2020)
Gini <- Gini[,c("iso3c", "date", "value")]
names(Gini)
names(Gini)<-c("iso3c", "date", "Gini")
#Change date to numeric
class(Gini$date)
Gini$date<-as.numeric(Gini$date)
#Tibble:
# A tibble: 1,012 x 3
iso3c date Gini
<chr> <dbl> <dbl>
1 ALB 2017 33.2
2 ALB 2016 33.7
3 ALB 2015 32.9
4 ALB 2014 34.6
5 ALB 2012 29
6 ALB 2008 30
7 ALB 2005 30.6
8 DZA 2011 27.6
9 AGO 2018 51.3
10 AGO 2008 42.7
# … with 1,002 more rows
Then I try to lag this estimate by one year
#Lag Gini
lg <- function(x)c(NA, x[1:(length(x)-1)])
Lagged.Gini<-ddply(Gini, ~ iso3c, transform, Gini.lag.1 = lg(Gini))
tibble(Lagged.Gini)
# A tibble: 1,032 x 4
iso3c date Gini Gini.lag.1
<chr> <dbl> <dbl> <dbl>
1 AGO 2018 51.3 NA
2 AGO 2008 42.7 51.3
3 ALB 2017 33.2 NA
4 ALB 2016 33.7 33.2
5 ALB 2015 32.9 33.7
6 ALB 2014 34.6 32.9
7 ALB 2012 29 34.6
8 ALB 2008 30 29
9 ALB 2005 30.6 30
10 ARE 2014 32.5 NA
Unfortunately, my problem is that when years are missing the lag does not recognize that year is missing and just puts the most recent year as the lag. Ex: country "ALB"'s Gini estimate is not lagged by one year in 2012 it lags to the next year which is 2008.
I would want the final data to look the same but how I edited below -- and ideally to be able to lag for multiple years:
# A tibble: 1,032 x 4
iso3c date Gini Gini.lag.1
<chr> <dbl> <dbl> <dbl>
1 AGO 2018 51.3 NA
AGO 2017 NA 51.3
2 AGO 2008 42.7 NA
AGO 2007 NA 42.7
3 ALB 2017 33.2 NA
4 ALB 2016 33.7 33.2
5 ALB 2015 32.9 33.7
6 ALB 2014 34.6 32.9
ALB 2013 NA 29
7 ALB 2012 29 NA
8 ALB 2008 30 29
9 ALB 2005 30.6 30
10 ARE 2014 32.5 NA
pseudospin's answer is great for base R. Since you're using tibbles, here's a tidyverse version with the same effect:
Gini <- readr::read_table("
iso3c date Gini
ALB 2017 33.2
ALB 2016 33.7
ALB 2015 32.9
ALB 2014 34.6
ALB 2012 29
ALB 2008 30
ALB 2005 30.6
DZA 2011 27.6
AGO 2018 51.3
AGO 2008 42.7")
library(dplyr)
Gini %>%
transmute(iso3c, date = date - 1, Gini.lag.1 = Gini) %>%
full_join(Gini, ., by = c("iso3c", "date")) %>%
arrange(iso3c, desc(date))
# # A tibble: 17 x 4
# iso3c date Gini Gini.lag.1
# <chr> <dbl> <dbl> <dbl>
# 1 AGO 2018 51.3 NA
# 2 AGO 2017 NA 51.3
# 3 AGO 2008 42.7 NA
# 4 AGO 2007 NA 42.7
# 5 ALB 2017 33.2 NA
# 6 ALB 2016 33.7 33.2
# 7 ALB 2015 32.9 33.7
# 8 ALB 2014 34.6 32.9
# 9 ALB 2013 NA 34.6
# 10 ALB 2012 29 NA
# 11 ALB 2011 NA 29
# 12 ALB 2008 30 NA
# 13 ALB 2007 NA 30
# 14 ALB 2005 30.6 NA
# 15 ALB 2004 NA 30.6
# 16 DZA 2011 27.6 NA
# 17 DZA 2010 NA 27.6
If you need to do this n times (one more lag each time), you can extend it programmatically this way:
Ginilags <- lapply(1:3, function(lg) {
z <- transmute(Gini, iso3c, date = date - lg, Gini)
names(z)[3] <- paste0("Gini.lag.", lg)
z
})
Reduce(function(a,b) full_join(a, b, by = c("iso3c", "date")),
c(list(Gini), Ginilags)) %>%
arrange(iso3c, desc(date))
# # A tibble: 28 x 6
# iso3c date Gini Gini.lag.1 Gini.lag.2 Gini.lag.3
# <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 AGO 2018 51.3 NA NA NA
# 2 AGO 2017 NA 51.3 NA NA
# 3 AGO 2016 NA NA 51.3 NA
# 4 AGO 2015 NA NA NA 51.3
# 5 AGO 2008 42.7 NA NA NA
# 6 AGO 2007 NA 42.7 NA NA
# 7 AGO 2006 NA NA 42.7 NA
# 8 AGO 2005 NA NA NA 42.7
# 9 ALB 2017 33.2 NA NA NA
# 10 ALB 2016 33.7 33.2 NA NA
# # ... with 18 more rows
Using dplyr & tidyr from tidyverse, you can do a rowwise mutate to find years which match the year in the current row minus 1.
library(tidyverse)
Gini %>%
rowwise() %>%
mutate(Gini.lag.1 = list(Gini$Gini[date-1 == Gini$date])) %>%
unnest(c(Gini.lag.1), keep_empty = T)
You could create a copy of the original table, but with the date having one year subtracted off. Then just join the two together on the iso3c and date columns to get the final result as you want it.
Like this
Gini_lagged <- data.frame(
iso3c = Gini$iso3c,
date = Gini$date-1,
Gini.lag.1 = Gini$Gini)
merge(Gini,Gini_lagged,all=TRUE)
I have a data set that is that I want to calculate z scores by their year.
Example:
Year Score
1999 120
1999 132
1998 120
1997 132
2000 120
2002 132
1998 160
1997 142
....etc
What I want is:
Year Score Z-Score
1999 120 1.2
1999 132 .01
1998 120 -.6
1997 132 1.1
2000 120 -.6
2002 132 0.5
1998 160 2.1
1997 142 .01
I have used the following code:
DF$ZScore<-if (DR$Year== 1997){
((DF$Score-220)/20)
} else if ((DR$Year== 1998){
((DF$Score-222)/19)
}...
}else{
((DF$Score-219)/21)
}
This is not working and I cannot figure out why. Any help is appreciated.
I'm using the gapminder data for simplicity, and also the built in scale function. You might want to build your own function to apply depending on exactly how you want to scale it.
this is a little clukly, but beause you want per year scaling, then you could group by the year and make a nested data frame.
Then using purr, you could go into each data.frame within a year, and scale the variable you want.
Then you would unnest the data again, and the variable would be scaled within each year.
library(tidyverse)
library(gapminder)
gapminder::gapminder %>%
group_by(year) %>%
nest() %>%
mutate(data = map(data,
~ mutate_at(.x, vars(lifeExp, pop),
list(scale = scale)))) %>%
unnest(data)
#> # A tibble: 1,704 x 8
#> # Groups: year [12]
#> year country continent lifeExp pop gdpPercap lifeExp_scale[,…
#> <int> <fct> <fct> <dbl> <int> <dbl> <dbl>
#> 1 1952 Afghan… Asia 28.8 8.43e6 779. -1.66
#> 2 1952 Albania Europe 55.2 1.28e6 1601. 0.505
#> 3 1952 Algeria Africa 43.1 9.28e6 2449. -0.489
#> 4 1952 Angola Africa 30.0 4.23e6 3521. -1.56
#> 5 1952 Argent… Americas 62.5 1.79e7 5911. 1.10
#> 6 1952 Austra… Oceania 69.1 8.69e6 10040. 1.64
#> 7 1952 Austria Europe 66.8 6.93e6 6137. 1.45
#> 8 1952 Bahrain Asia 50.9 1.20e5 9867. 0.154
#> 9 1952 Bangla… Asia 37.5 4.69e7 684. -0.947
#> 10 1952 Belgium Europe 68 8.73e6 8343. 1.55
#> # … with 1,694 more rows, and 1 more variable: pop_scale[,1] <dbl>
Created on 2020-06-25 by the reprex package (v0.3.0)
I have a dataframe with crime data and associated "prices", organized by country and year (although I don't think this is important here). Here is a subset of my data:
> crime
# A tibble: 8 x 8
iso year theft robbery burglary theft_price robbery_price burglary_price
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 ALB 2003 3694 199 874 32.9 115 49.3
2 ALB 2004 3694 199 874 38.2 134 57.3
3 ALB 2005 3694 199 874 42.8 150 64.2
4 ALB 2006 3450 164 779 47.0 165 70.5
5 AUS 2003 722334 14634 586266 408.4 1427 612.4
6 AUS 2004 636717 14634 512551 481.3 1683 721.2
7 AUS 2005 598700 14634 468558 536.7 1877 804.5
8 AUS 2006 594111 14634 433974 564.8 1973 846.5
I want to create new columns that contain the product of each crime type with its price, so theft x theft_price = theft_prod, etc. In my actual dataset I have more crime types so I need something that is scalable to more variables than this subset contains.
I like the syntax of the dplyr package, so I to use something like this, but I cannot find the solution. I think it is not possible to reference other variables than the ones in vars(). Correct?
crime %>%
mutate_at(vars(theft, robbery, burglary),
funs(prod = . * ????))
Thanks.
Use dplyr and tidyr:
library(dplyr); library(tidyr);
df %>%
gather(crime, value, -iso, -year) %>%
separate(crime, c('crime', 'type'), sep='_', fill = 'right') %>%
replace_na(list(type = 'amount')) %>%
spread(type, value) %>%
transmute(
iso = iso, year = year,
crime = paste(crime, 'prod', sep = '_'),
prod = amount * price
) %>%
spread(crime, prod)
# iso year burglary_prod robbery_prod theft_prod
#1 ALB 2003 43088.2 22885 121532.6
#2 ALB 2004 50080.2 26666 141110.8
#3 ALB 2005 56110.8 29850 158103.2
#4 ALB 2006 54919.5 27060 162150.0
#5 AUS 2003 359029298.4 20882718 295001205.6
#6 AUS 2004 369651781.2 24629022 306451892.1
#7 AUS 2005 376954911.0 27468018 321322290.0
#8 AUS 2006 367358991.0 28872882 335553892.8
Another option without data reshaping, assuming the columns' names follow the crime_price convention:
library(tidyverse)
# find out the crimes columns
crimes = grep('^(?!.*_price$)', names(df)[-c(1,2)], perl = T, value = T)
# construct the crimes prices columns
crimes_prices = paste(crimes, 'price', sep = '_')
crimes_prod = paste(crimes, 'prod', sep = '_')
# loop through crime and crime price columns and multiply them
map2(crimes, crimes_prices, ~ df[[.x]] * df[[.y]]) %>%
set_names(crimes_prod) %>%
as_tibble() %>%
bind_cols(select(df, iso, year))
# A tibble: 8 x 5
# theft_prod robbery_prod burglary_prod iso year
# <dbl> <int> <dbl> <fct> <int>
#1 121533. 22885 43088. ALB 2003
#2 141111. 26666 50080. ALB 2004
#3 158103. 29850 56111. ALB 2005
#4 162150 27060 54920. ALB 2006
#5 295001206. 20882718 359029298. AUS 2003
#6 306451892. 24629022 369651781. AUS 2004
#7 321322290 27468018 376954911 AUS 2005
#8 335553893. 28872882 367358991 AUS 2006
Doing this kind of manipulation in the tidyverse is best done by making sure your data is tidy by reshaping it. A purrr approach is also possible but is likely reliant on the order of your columns, which might not always be reliable. Instead, you can do the following:
gather up all your measure columns
mutate a new column measure_type that indicates whether it is a count or price, and remove the _price from crime_type. Now we have separate columns for the type of crime and the metric we are using for that crime. Each row is a single iso-year-crime-metric combination.
spread the crime types back out so now we have separate count and price columns for all crimes, and then multiply with mutate.
(optional) if you want to put it back in your wide format, we just gather up count and price and our new product column, unite to combine with the crime type and spread back out.
library(tidyverse)
tbl <- read_table2(
"iso year theft robbery burglary theft_price robbery_price burglary_price
ALB 2003 3694 199 874 32.9 115 49.3
ALB 2004 3694 199 874 38.2 134 57.3
ALB 2005 3694 199 874 42.8 150 64.2
ALB 2006 3450 164 779 47.0 165 70.5
AUS 2003 722334 14634 586266 408.4 1427 612.4
AUS 2004 636717 14634 512551 481.3 1683 721.2
AUS 2005 598700 14634 468558 536.7 1877 804.5
AUS 2006 594111 14634 433974 564.8 1973 846.5"
)
tidy_tbl <- tbl %>%
gather(crime_type, measure, -iso, - year) %>%
mutate(
measure_type = if_else(str_detect(crime_type, "_price$"), "price", "count"),
crime_type = str_remove(crime_type, "_price")
) %>%
spread(measure_type, measure) %>%
mutate(product = count * price)
tidy_tbl
#> # A tibble: 24 x 6
#> iso year crime_type count price product
#> <chr> <int> <chr> <dbl> <dbl> <dbl>
#> 1 ALB 2003 burglary 874 49.3 43088.
#> 2 ALB 2003 robbery 199 115 22885
#> 3 ALB 2003 theft 3694 32.9 121533.
#> 4 ALB 2004 burglary 874 57.3 50080.
#> 5 ALB 2004 robbery 199 134 26666
#> 6 ALB 2004 theft 3694 38.2 141111.
#> 7 ALB 2005 burglary 874 64.2 56111.
#> 8 ALB 2005 robbery 199 150 29850
#> 9 ALB 2005 theft 3694 42.8 158103.
#> 10 ALB 2006 burglary 779 70.5 54920.
#> # ... with 14 more rows
tidy_tbl %>%
gather(measure_type, measure, count:product) %>%
unite("colname", crime_type, measure_type) %>%
spread(colname, measure)
#> # A tibble: 8 x 11
#> iso year burglary_count burglary_price burglary_product robbery_count
#> <chr> <int> <dbl> <dbl> <dbl> <dbl>
#> 1 ALB 2003 874 49.3 43088. 199
#> 2 ALB 2004 874 57.3 50080. 199
#> 3 ALB 2005 874 64.2 56111. 199
#> 4 ALB 2006 779 70.5 54920. 164
#> 5 AUS 2003 586266 612. 359029298. 14634
#> 6 AUS 2004 512551 721. 369651781. 14634
#> 7 AUS 2005 468558 804. 376954911 14634
#> 8 AUS 2006 433974 846. 367358991 14634
#> # ... with 5 more variables: robbery_price <dbl>, robbery_product <dbl>,
#> # theft_count <dbl>, theft_price <dbl>, theft_product <dbl>
Created on 2018-08-15 by the reprex package (v0.2.0).