应用 rollmean,但如果公司没有 k > 2,则保留单个值

Apply rollmean, but keeping the single value if a company does not have k > 2

我有一个数据集,我希望将 rollmean 应用于平滑数据值。然而,对于我的一些观察,我只有第一个值,所以我会保留它而不是默认值 NA。为实现这一点,我过滤了那些我拥有超过 k>2 的数据,因此我可以简单地应用以下代码。对于那些 k < 2 的,我只是在后面插入它们。我有更好的方法吗?

df <- tibble(city = sample(LETTERS[1:11], 10, rep=TRUE), 
    deaths = sample(1000:10000, 10, rep=TRUE))
df %>%
    dplyr::arrange(desc(city)) %>% 
    dplyr::group_by(city) %>% 
    dplyr::mutate(roll = zoo::rollmean(deaths, k = 2, fill = NA, align="right")) %>% 
    dplyr::ungroup()
# A tibble: 10 x 3
   city  deaths  roll
   <chr>  <int> <dbl>
 1 K       9292   NA 
 2 K       7339 8316.
 3 J       3537   NA 
 4 J       1207 2372 
 5 G       4994   NA 
 6 F       2185   NA 
 7 F       1408 1796.
 8 E       4254   NA 
 9 D       5269   NA 
10 B       5448   NA 

我们可以使用 partial = TRUE

library(dplyr)
df %>%
    dplyr::arrange(desc(city)) %>% 
    dplyr::group_by(city) %>% 
    dplyr::mutate(roll = zoo::rollmean(deaths, k = 2, fill = NA, 
                 align="right", partial = TRUE)) %>% 
    dplyr::ungroup()
# A tibble: 10 x 3
#   city  deaths  roll
#   <chr>  <int> <dbl>
# 1 K       2128   NA 
# 2 K       1877 2002.
# 3 G       2300   NA 
# 4 G       9228 5764 
# 5 E       6921 6921 -> single value
# 6 C       9676 9676 -> single value
# 7 B       2798   NA 
# 8 B       9920 6359 
# 9 A       9521   NA 
#10 A       8844 9182.

根据您的预期输出,您可以选择以下选项之一。 rollmean(... , align = 'right') 也等于 rollmeanr.

  1. 您可以检查组中的行数并保留行数的 death 值 = 1。请注意,这仍将为第一个值提供 NA,其中行数大于 1.
df %>%
  dplyr::arrange(desc(city)) %>% 
  dplyr::group_by(city) %>%
  dplyr::mutate(roll = if(n() == 1) deaths else zoo::rollmeanr(deaths, k = 2, fill = NA))
  1. 您可以使用 fill = first(deaths) 获取第一个值作为所有第一个值的默认值。这会将每个组中的 NA 替换为该组的第一个值。所以将最后一行更改为:
dplyr::mutate(roll = zoo::rollmeanr(deaths, k = 2, fill = first(deaths)))
  1. 您可以将 rollaplyrpartial = TRUE 一起使用。当 k = 2 时,它会给出与 (2) 相同的输出,但如果你更改 window-size,你会看到不同之处。
dplyr::mutate(roll = zoo::rollapplyr(deaths, width = 2, FUN = mean, partial = TRUE))