0

我有一个包含很多缺失值的大型数据集,我想通过组“名称”线性或移动平均来估算它。

d <-  data.frame(
  name = c('a', 'a','a','a','b','b','b','b','c','c','c','c'),
  year = c(1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4),
  V = c(NA, 21, 31, 41, 11, NA, NA, 41, NA, NA, NA, 41),
  W = c(11, NA, 31, 41, 11, 21, NA, NA, NA, NA, 31, NA),
  X = c(11, 21, NA, 41, NA, 21, NA, 41, 11, NA, NA, NA),
  Y = c(11, 21, 31, NA, NA, 21, 31, NA, NA, 21, NA, NA),
  Z = c(NA, NA, 31, 41, 11, NA, 31, NA, NA, NA, NA, NA)
)

> d
   name year  V  W  X  Y  Z
1     a    1 NA 11 11 11 NA
2     a    2 21 NA 21 21 NA
3     a    3 31 31 NA 31 31
4     a    4 41 41 41 NA 41
5     b    1 11 11 NA NA 11
6     b    2 NA 21 21 21 NA
7     b    3 NA NA NA 31 31
8     b    4 41 NA 41 NA NA
9     c    1 NA NA 11 NA NA
10    c    2 NA NA NA 21 NA
11    c    3 NA 31 NA NA NA
12    c    4 41 NA NA NA NA

希望结果可以像下面这样关闭:

   name year  V  W  X  Y  Z
1     a    1 11 11 11 11 11
2     a    2 21 21 21 21 21
3     a    3 31 31 31 31 31
4     a    4 41 41 41 41 41
5     b    1 11 11 11 11 11
6     b    2 21 21 21 21 21
7     b    3 31 31 31 31 31
8     b    4 41 41 41 41 41
9     c    1 11 11 11 11 NA
10    c    2 21 21 21 21 NA
11    c    3 31 31 31 31 NA
12    c    4 41 41 41 41 NA

我找到了这个这个。在没有 groupby 的情况下尝试了以下操作,但没有成功:

data.frame(lapply(d, function(X) approxfun(seq_along(X), X)(seq_along(X))))
imputeTS::na_ma(d, k = 2, weighting = "simple")

第一个报错如下:

Error in approxfun(seq_along(X), X) : 
  need at least two non-NA values to interpolate
In addition: Warning message:
In xy.coords(x, y, setLab = FALSE) :
 Error in approxfun(seq_along(X), X) : 
  need at least two non-NA values to interpolate

所以我尝试了第二个,它一直加载很长时间,但什么也没发生。根据第一个链接的回复,

该包需要时间序列/向量输入(这就是为什么必须单独调用每一列的原因)。

任何帮助是极大的赞赏!

4

2 回答 2

3

你可以使用zoo::na.spline-

library(dplyr)

d %>%
  group_by(name) %>%
  mutate(across(V:Z, zoo::na.spline, na.rm = FALSE)) %>%
  ungroup

#   name   year     V     W     X     Y     Z
#   <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 a         1    11    11    11    11    11
# 2 a         2    21    21    21    21    21
# 3 a         3    31    31    31    31    31
# 4 a         4    41    41    41    41    41
# 5 b         1    11    11    11    11    11
# 6 b         2    21    21    21    21    21
# 7 b         3    31    31    31    31    31
# 8 b         4    41    41    41    41    41
# 9 c         1    41    31    11    21    NA
#10 c         2    41    31    11    21    NA
#11 c         3    41    31    11    21    NA
#12 c         4    41    31    11    21    NA

对于name"c"我认为很难仅从 1 个数字中估算缺失值。

于 2022-02-05T08:39:53.160 回答
1

我看到的一个问题是,您要估算的某些系列只有 1 个非 NA 值,因此无法成功应用imputeTSna_mana_interpolation其他软件包,因为这些至少需要 2 个非 NA 值。

这就是为什么在这个解决方案中我为你创建了一个impute_select函数,让你选择,什么时候> 1值或存在,什么时候确切地== 1存在值或只有 NA。

在这种情况下,当存在 > 1 个值时,它使用na_ma,但您也可以在此处使用 imputeTS 中的 na_interpoltion 或任何其他插补函数。当仅存在 1 个值时,它使用,na_locf因为此方法也仅适用于系列中的 1 个值。当系列中没有非 NA 值时,它使用 na_replace,只需将所有 NA 替换为默认值(我只是将其设置为 11)

通过调整此函数,您应该能够单独调整序列中不同数量的 NA 的插补。

library("imputeTS")

d <-  data.frame(
  name = c('a', 'a','a','a','b','b','b','b','c','c','c','c'),
  year = c(1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4),
  V = c(NA, 21, 31, 41, 11, NA, NA, 41, NA, NA, NA, 41),
  W = c(11, NA, 31, 41, 11, 21, NA, NA, NA, NA, 31, NA),
  X = c(11, 21, NA, 41, NA, 21, NA, 41, 11, NA, NA, NA),
  Y = c(11, 21, 31, NA, NA, 21, 31, NA, NA, 21, NA, NA),
  Z = c(NA, NA, 31, 41, 11, NA, 31, NA, NA, NA, NA, NA)
)

impute_select <- function(x) {
  # select a method to use when more than 1 values are available
  if (sum(!is.na(x)) > 1) {
    result <- na_ma(x)
  }
  # Select value when only 1 value is in series
  if (sum(!is.na(x)) == 1) {
    result <- na_locf(x)
  }
  # Select method, when no non-NA value is present
  else {
    result <- na_replace(x, 11)
  }
}

# This code is to apply the function row-wise to your data frame
# Since usually the imputation would happen column-wise instead
d[,3:7] <- t(apply(d[,3:7], MARGIN =1, FUN = impute_select))

d

这是结果(希望正是你想要的):

   name year  V  W  X  Y  Z
1     a    1 11 11 11 11 11
2     a    2 21 11 21 21 11
3     a    3 31 31 11 31 31
4     a    4 41 41 41 11 41
5     b    1 11 11 11 11 11
6     b    2 11 21 21 21 11
7     b    3 11 11 11 31 31
8     b    4 41 11 41 11 11
9     c    1 11 11 11 11 11
10    c    2 21 21 21 21 21
11    c    3 31 31 31 31 31
12    c    4 41 41 41 41 41
于 2022-02-06T14:34:10.940 回答