由于 R 中的 NA 值不应删除而导致 Rollapplyr 函数出现问题

问题描述

我有一个数据框:

      date comp  ei
1   1/1/73    A  NA
2   1/4/73    A 0.6
3   1/7/73    A 0.7
4  1/10/73    A 0.9
5   1/1/74    A 0.4
6   1/4/74    A 0.5
7   1/7/74    A 0.7
8  1/10/74    A 0.7
9   1/1/75    A 0.4
10  1/4/75    A 0.5
11  1/1/73    B 0.8
12  1/4/73    B 0.8
13  1/7/73    B 0.5
14 1/10/73    B 0.6
15  1/1/74    B 0.3
16  1/4/74    B 0.2
17  1/1/73    C  NA
18  1/4/73    C 0.6
19  1/7/73    C 0.4
20 1/10/73    C 0.8
21  1/1/74    C 0.7
22  1/4/74    C 0.9
23  1/7/74    C 0.4
24 1/10/74    C 0.3

我想计算滚动标准。 ei 的偏差按 comp 分组。我想要最后 8 行的滚动标准偏差 - 但如果只有 6 行存在,到目前为止,它仍然应该采用滚动标准差。那些的偏差。所以我在这代码中使用了 width = 8 和 partial = 6:

roll <- function(z) rollapplyr(z,width = 8,FUN = sd,fill = NA,partial = 6)  
df <- transform(df,roll = ave(ei,comp,FUN = roll)) 

然而,由于我的某些 'ei' 值是 'NA',函数的部分部分不起作用,因为在过去 8 行之一中有一个 NA。所以当然在 6 行之后是 std。开发是 NA。仅对于 comp = B,部分 = 6 有效。结果如下:

      date comp  ei      roll
1   1/1/73    A  NA        NA
2   1/4/73    A 0.6        NA
3   1/7/73    A 0.7        NA
4  1/10/73    A 0.9        NA
5   1/1/74    A 0.4        NA
6   1/4/74    A 0.5        NA
7   1/7/74    A 0.7        NA
8  1/10/74    A 0.7        NA
9   1/1/75    A 0.4 0.1726888
10  1/4/75    A 0.5 0.1772811
11  1/1/73    B 0.8        NA
12  1/4/73    B 0.8        NA
13  1/7/73    B 0.5        NA
14 1/10/73    B 0.6        NA
15  1/1/74    B 0.3        NA
16  1/4/74    B 0.2 0.2503331
17  1/1/73    C  NA        NA
18  1/4/73    C 0.6        NA
19  1/7/73    C 0.4        NA
20 1/10/73    C 0.8        NA
21  1/1/74    C 0.7        NA
22  1/4/74    C 0.9        NA
23  1/7/74    C 0.4        NA
24 1/10/74    C 0.3        NA

我更希望我的结果看起来像下面那样,第一个标准。 dev 是针对前 6 个值(不是 NA)的第 7 行中的 comp A 计算的,其中 comp C 具有 std。 dev 在第 23 和 24 行:

      date comp  ei      roll
1   1/1/73    A  NA        NA
2   1/4/73    A 0.6        NA
3   1/7/73    A 0.7        NA
4  1/10/73    A 0.9        NA
5   1/1/74    A 0.4        NA
6   1/4/74    A 0.5        NA
7   1/7/74    A 0.7 0.1751190
8  1/10/74    A 0.7 0.1618347
9   1/1/75    A 0.4 0.1726888
10  1/4/75    A 0.5 0.1772811
11  1/1/73    B 0.8        NA
12  1/4/73    B 0.8        NA
13  1/7/73    B 0.5        NA
14 1/10/73    B 0.6        NA
15  1/1/74    B 0.3        NA
16  1/4/74    B 0.2 0.2503331
17  1/1/73    C  NA        NA
18  1/4/73    C 0.6        NA
19  1/7/73    C 0.4        NA
20 1/10/73    C 0.8        NA
21  1/1/74    C 0.7        NA
22  1/4/74    C 0.9        NA
23  1/7/74    C 0.4 0.2065591
24 1/10/74    C 0.3 0.2267787

在计算滚动标准之前,如何在不运行 na.omit 代码的情况下执行此操作。开发?我不想删除 NA 的原因是我需要带有 comp 和日期的行(以及我的真实数据集中的其他列)。此外,在我的真实数据集中,删除我的 NA 值可能会导致在一个时期的中间删除 NA,以便滚动 std。开发函数不符合日期,我的结果会出错。

有没有办法在不删除 NA 值的情况下处理这个问题?

解决方法

1) 如果至少有 6 个非 NA,FUN 会计算 sd,否则返回 NA。 然后按照问题继续。

library(zoo)

df$date <- as.Date(df$date,"%d/%m/%y")
FUN <- function(x) if (length(na.omit(x)) >= 6) sd(x,na.rm = TRUE) else NA
roll <- function(z) rollapplyr(z,width = 8,FUN = FUN,fill = NA,partial = 6)  
transform(df,roll = ave(ei,comp,FUN = roll)) 

2) 另一种可能是使用 na.omit 然后将结果与原始数据框合并。

library(zoo)

df$date <- as.Date(df$date,"%d/%m/%y")
roll <- function(z) rollapplyr(z,FUN = sd,partial = 6)  

df_roll_0 <- transform(na.omit(df),FUN = roll)) 
df_roll_m <- merge(df,df_roll_0,all = TRUE)
o <- with(df_roll_m,order(comp,date))
df_roll <- df_roll_m[o,]

2a) 这也可以用 dplyr/tidyr 表示:

library(dplyr)
library(tidyr)
library(zoo)
df$date <- as.Date(df$date,partial = 6)  

df_roll_0 <- df %>%
  drop_na %>%
  group_by(comp) %>%
  mutate(roll = roll(ei)) %>%
  ungroup

df %>%
  left_join(df_roll_0)

注意

Lines <- "      date comp  ei
1   1/1/73    A  NA
2   1/4/73    A 0.6
3   1/7/73    A 0.7
4  1/10/73    A 0.9
5   1/1/74    A 0.4
6   1/4/74    A 0.5
7   1/7/74    A 0.7
8  1/10/74    A 0.7
9   1/1/75    A 0.4
10  1/4/75    A 0.5
11  1/1/73    B 0.8
12  1/4/73    B 0.8
13  1/7/73    B 0.5
14 1/10/73    B 0.6
15  1/1/74    B 0.3
16  1/4/74    B 0.2
17  1/1/73    C  NA
18  1/4/73    C 0.6
19  1/7/73    C 0.4
20 1/10/73    C 0.8
21  1/1/74    C 0.7
22  1/4/74    C 0.9
23  1/7/74    C 0.4
24 1/10/74    C 0.3"
df <- read.table(text = Lines)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...