It's a bit ugly maybe, but is this something you are looking for?
JW
require(dplyr)
require(stringr)
df <- data.frame(Country.Code = rep("ALB",8),
Indicator.ID = c("3.2.1", "3.2.2", "3.2.3", "3.2.4",
"3.3.1", "3.3.2", "3.3.3", "3.3.4"),
Indicator.Value = c(0.37, 0.35, 0.35, 0.32, 0.47, 0.35, 0.35, 0.32))
df_1 <- df %>% mutate(group_id = str_sub(Indicator.ID, 1, 3)) %>%
group_by(Country.Code, group_id) %>%
transmute(Indicator.ID = str_c(Indicator.ID,"1", sep ="."),
Indicator.Value = Indicator.Value - lead(Indicator.Value,1)) %>%
ungroup() %>%
select(-group_id)
bind_rows(df, df_1)
# Country.Code Indicator.ID Indicator.Value
# 1 ALB 3.2.1 0.37
# 2 ALB 3.2.2 0.35
# 3 ALB 3.2.3 0.35
# 4 ALB 3.2.4 0.32
# 5 ALB 3.3.1 0.47
# 6 ALB 3.3.2 0.35
# 7 ALB 3.3.3 0.35
# 8 ALB 3.3.4 0.32
# 9 ALB 3.2.1.1 0.02
# 10 ALB 3.2.2.1 0.00
# 11 ALB 3.2.3.1 0.03
# 12 ALB 3.2.4.1 NA
# 13 ALB 3.3.1.1 0.12
# 14 ALB 3.3.2.1 0.00
# 15 ALB 3.3.3.1 0.03
# 16 ALB 3.3.4.1 NA