我正在尝试使用另一列中给出的增长率在系列中最后一个非缺失值之后向前推断缺失值。
这是下面的一个玩具示例。我的数据根据产品和地区进行分组,并且应按分组内的年份排列。我有带有一些 NA 值的销售数据。我有兴趣使用 World.growth 率来推断销售的 NA 值,该值出现在每个系列中最后一个非缺失值之后。例如,产品 = 1,区域 = 1,我希望 1973 年的 Interpolated.sales 为 1972 年值 * 1973 年给出的 World.growth 值。
这是我的数据:
> library(openxlsx)
> library(dplyr)
>
> sales.data <- read.xlsx("\\Interpolate_sales.xlsx", sheet = 1)
>
> print(sales.data)
Product Region Year Sales World.growth Extrapolated.sales
1 1 1 1970 NA 0.88 NA
2 1 1 1971 141.906913 0.72 141.906913
3 1 1 1972 9.605398 1.01 9.605398
4 1 1 1973 NA 1.18 11.334370
5 1 1 1974 NA 0.84 9.520871
6 1 2 1970 60.062486 0.88 60.062486
7 1 2 1971 124.904150 0.72 124.904150
8 1 2 1972 NA 1.01 126.153191
9 1 2 1973 NA 1.18 148.860765
10 1 2 1974 NA 0.84 125.043043
11 1 2 1975 NA 1.23 153.802943
12 1 3 1970 63.298780 0.88 63.298780
13 1 3 1971 90.219126 0.72 90.219126
14 1 3 1972 107.271043 1.01 107.271043
15 1 3 1973 129.122561 1.18 129.122561
16 1 3 1974 NA 0.84 108.462951
这是我的 dplyr 尝试(是否有更好的方法通过编写函数或其他东西?我想如果我想在系列开始时向后推断缺失值,这也会很方便。)
> sales.data.extrapolated <- sales.data %>%
+ group_by(Product, Region) %>%
+ arrange(Product, Region, Year) %>%
+ mutate(Extrapolated.sales.manual = case_when(
+ row_number() > max(which(!is.na(Sales))) ~ lag(Sales) * World.growth,
+ TRUE ~ Sales
+ ))
>
> print(sales.data.extrapolated)
# A tibble: 16 × 7
# Groups: Product, Region [3]
Product Region Year Sales World.growth Extrapolated.sales Extrapolated.sales.manual
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 1 1970 NA 0.88 NA NA
2 1 1 1971 142. 0.72 142. 142.
3 1 1 1972 9.61 1.01 9.61 9.61
4 1 1 1973 NA 1.18 11.3 11.3
5 1 1 1974 NA 0.84 9.52 NA
6 1 2 1970 60.1 0.88 60.1 60.1
7 1 2 1971 125. 0.72 125. 125.
8 1 2 1972 NA 1.01 126. 126.
9 1 2 1973 NA 1.18 149. NA
10 1 2 1974 NA 0.84 125. NA
11 1 2 1975 NA 1.23 154. NA
12 1 3 1970 63.3 0.88 63.3 63.3
13 1 3 1971 90.2 0.72 90.2 90.2
14 1 3 1972 107. 1.01 107. 107.
15 1 3 1973 129. 1.18 129. 129.
16 1 3 1974 NA 0.84 108. 108.
如您所见,这仅计算第一个缺失值的值,除此之外不再计算。
这是一个“归约”问题,必须逐步完成,因为“这一行”的新值取决于“最后一行”值的结果……R 中的正常向量化运算不知道更新的值计算整个向量之前的值。
为此,我将使用
Reduce
,但如果您已经在使用 purrr::accumulate
,那么 purrr
几乎可以作为替代品。
sales.data %>%
group_by(Product, Region) %>%
mutate(
newcol = Reduce(function(prevval, ind) coalesce(Sales[ind], prevval * World.growth[ind]),
row_number(), init = NA, accumulate = TRUE)[-1]
) %>%
ungroup()
# # A tibble: 16 × 7
# Product Region Year Sales World.growth Extrapolated.sales newcol
# <int> <int> <int> <dbl> <dbl> <dbl> <dbl>
# 1 1 1 1970 NA 0.88 NA NA
# 2 1 1 1971 142. 0.72 142. 142.
# 3 1 1 1972 9.61 1.01 9.61 9.61
# 4 1 1 1973 NA 1.18 11.3 11.3
# 5 1 1 1974 NA 0.84 9.52 9.52
# 6 1 2 1970 60.1 0.88 60.1 60.1
# 7 1 2 1971 125. 0.72 125. 125.
# 8 1 2 1972 NA 1.01 126. 126.
# 9 1 2 1973 NA 1.18 149. 149.
# 10 1 2 1974 NA 0.84 125. 125.
# 11 1 2 1975 NA 1.23 154. 154.
# 12 1 3 1970 63.3 0.88 63.3 63.3
# 13 1 3 1971 90.2 0.72 90.2 90.2
# 14 1 3 1972 107. 1.01 107. 107.
# 15 1 3 1973 129. 1.18 129. 129.
# 16 1 3 1974 NA 0.84 108. 108.