使用 rollmean 过滤掉具有阈值的 NA
Using rollmean filtering out NA with threshold
我正在尝试将 rollapply mean 函数应用于具有大量缺失数据和散布在整个缺失数据中的单点的数据框。使用我当前的 rollapply 形式,只需要一个非 NaN 值并将其平均为所有周围的值。我的目标是保留至少有一半平均值的值,并删除超过 50% NaN
数据的所有值。下面是我做的一个简单的例子
library(zoo)
a <- c(0:20)
ind <- c(10:15)
ind2 <- c(10:12,14)
b <- a
b[ind] <- NaN
c <- a
c[ind2] <- NaN
df <- data.frame(a=a,b=b,c=c)
dfroll <- as.data.frame(rollapply(df,width=5,mean,na.rm=T,fill=NA))
结果如下data.frame
dfroll
a b c
1 NA NA NA
2 NA NA NA
3 2 2.0 2.00000
4 3 3.0 3.00000
5 4 4.0 4.00000
6 5 5.0 5.00000
7 6 6.0 6.00000
8 7 6.5 6.50000
9 8 7.0 7.00000
10 9 7.5 7.50000
11 10 8.0 10.00000
12 11 NaN 12.00000
13 12 NaN 13.00000
14 13 15.0 13.66667
15 14 15.5 14.25000
16 15 16.0 15.50000
17 16 16.5 16.00000
18 17 17.0 17.00000
19 18 18.0 18.00000
20 NA NA NA
21 NA NA NA
对于此示例,我希望所有具有 >= 3 NaN
个值的值都产生 NaN
。这将是 b 列上的 10:15 行和 c 列上的 10:13 行。如果单元格周围的数据有限,我将如何设置此阈值以通过 NaN
而不是平均值?
想要的结果:
bdesired <- dfroll$b
bdesired[c(10:15)] <- NaN
cdesired <- dfroll$c
cdesired[c(10:13)] <- NaN
dfdesired <- data.frame(a=dfroll$a,b=bdesired,c=cdesired)
dfdesired
a b c
1 NA NA NA
2 NA NA NA
3 2 2.0 2.00000
4 3 3.0 3.00000
5 4 4.0 4.00000
6 5 5.0 5.00000
7 6 6.0 6.00000
8 7 6.5 6.50000
9 8 7.0 7.00000
10 9 NaN NaN
11 10 NaN NaN
12 11 NaN NaN
13 12 NaN NaN
14 13 NaN 13.50000
15 14 NaN 14.33333
16 15 16.0 16.00000
17 16 16.5 16.50000
18 17 17.0 17.00000
19 18 18.0 18.00000
20 NA NA NA
21 NA NA NA
使用 across(everything()
你可以对所有列进行操作,然后使用 rollsum(is.na())
我们计算 NAs
的数量,只有当它不是 3 或更高时我们计算rollmean
.
我只注意到 c-variable
的某些值在 dfroll
与 dfdesired
中略有不同。我的结果与 dfroll
.
中的结果相符
library(tidyverse)
df %>%
mutate(across(everything(),
~ifelse(rollsum(is.na(.x), 5, fill = NA) > 2, NaN, rollmean(.x, 5, fill = NA, na.rm = T))))
a b c
1 NA NA NA
2 NA NA NA
3 2 2.0 2.00000
4 3 3.0 3.00000
5 4 4.0 4.00000
6 5 5.0 5.00000
7 6 6.0 6.00000
8 7 6.5 6.50000
9 8 7.0 7.00000
10 9 NaN NaN
11 10 NaN NaN
12 11 NaN NaN
13 12 NaN NaN
14 13 NaN 13.66667
15 14 NaN 14.25000
16 15 16.0 15.50000
17 16 16.5 16.00000
18 17 17.0 17.00000
19 18 18.0 18.00000
20 NA NA NA
21 NA NA NA
1) 定义一个函数,如果其输入中有 thresh
或更多 NA 并且 returns 意味着 returns NaN non-NA 的其他情况。然后与 rollapply
一起使用。如果需要,使用 as.data.frame
将其转换为数据框,但由于数据完全是数字,将其作为矩阵可能就足够了。
w <- 5
thresh <- w/2
Mean <- function(x, thresh) if (sum(is.na(x)) > thresh) NaN else mean(x,na.rm=TRUE)
rollapply(df, w, Mean, thresh = thresh, fill = NA)
2) 另一种可能性是检查每个单元格中是否有超过阈值的 NA,如果是 return NaN,否则 return 滚动意思。如果需要数据框,请再次对结果使用 as.data.frame
。 (1) 比这个有优势,它只调用 roll*
一次而不是两次。
w <- 5
thresh <- w/2
ifelse(rollsum(is.na(df), w, fill = NA) > thresh, NaN,
rollmean(df, w, na.rm = TRUE, fill = NA))
我正在尝试将 rollapply mean 函数应用于具有大量缺失数据和散布在整个缺失数据中的单点的数据框。使用我当前的 rollapply 形式,只需要一个非 NaN 值并将其平均为所有周围的值。我的目标是保留至少有一半平均值的值,并删除超过 50% NaN
数据的所有值。下面是我做的一个简单的例子
library(zoo)
a <- c(0:20)
ind <- c(10:15)
ind2 <- c(10:12,14)
b <- a
b[ind] <- NaN
c <- a
c[ind2] <- NaN
df <- data.frame(a=a,b=b,c=c)
dfroll <- as.data.frame(rollapply(df,width=5,mean,na.rm=T,fill=NA))
结果如下data.frame
dfroll
a b c
1 NA NA NA
2 NA NA NA
3 2 2.0 2.00000
4 3 3.0 3.00000
5 4 4.0 4.00000
6 5 5.0 5.00000
7 6 6.0 6.00000
8 7 6.5 6.50000
9 8 7.0 7.00000
10 9 7.5 7.50000
11 10 8.0 10.00000
12 11 NaN 12.00000
13 12 NaN 13.00000
14 13 15.0 13.66667
15 14 15.5 14.25000
16 15 16.0 15.50000
17 16 16.5 16.00000
18 17 17.0 17.00000
19 18 18.0 18.00000
20 NA NA NA
21 NA NA NA
对于此示例,我希望所有具有 >= 3 NaN
个值的值都产生 NaN
。这将是 b 列上的 10:15 行和 c 列上的 10:13 行。如果单元格周围的数据有限,我将如何设置此阈值以通过 NaN
而不是平均值?
想要的结果:
bdesired <- dfroll$b
bdesired[c(10:15)] <- NaN
cdesired <- dfroll$c
cdesired[c(10:13)] <- NaN
dfdesired <- data.frame(a=dfroll$a,b=bdesired,c=cdesired)
dfdesired
a b c
1 NA NA NA
2 NA NA NA
3 2 2.0 2.00000
4 3 3.0 3.00000
5 4 4.0 4.00000
6 5 5.0 5.00000
7 6 6.0 6.00000
8 7 6.5 6.50000
9 8 7.0 7.00000
10 9 NaN NaN
11 10 NaN NaN
12 11 NaN NaN
13 12 NaN NaN
14 13 NaN 13.50000
15 14 NaN 14.33333
16 15 16.0 16.00000
17 16 16.5 16.50000
18 17 17.0 17.00000
19 18 18.0 18.00000
20 NA NA NA
21 NA NA NA
使用 across(everything()
你可以对所有列进行操作,然后使用 rollsum(is.na())
我们计算 NAs
的数量,只有当它不是 3 或更高时我们计算rollmean
.
我只注意到 c-variable
的某些值在 dfroll
与 dfdesired
中略有不同。我的结果与 dfroll
.
library(tidyverse)
df %>%
mutate(across(everything(),
~ifelse(rollsum(is.na(.x), 5, fill = NA) > 2, NaN, rollmean(.x, 5, fill = NA, na.rm = T))))
a b c
1 NA NA NA
2 NA NA NA
3 2 2.0 2.00000
4 3 3.0 3.00000
5 4 4.0 4.00000
6 5 5.0 5.00000
7 6 6.0 6.00000
8 7 6.5 6.50000
9 8 7.0 7.00000
10 9 NaN NaN
11 10 NaN NaN
12 11 NaN NaN
13 12 NaN NaN
14 13 NaN 13.66667
15 14 NaN 14.25000
16 15 16.0 15.50000
17 16 16.5 16.00000
18 17 17.0 17.00000
19 18 18.0 18.00000
20 NA NA NA
21 NA NA NA
1) 定义一个函数,如果其输入中有 thresh
或更多 NA 并且 returns 意味着 returns NaN non-NA 的其他情况。然后与 rollapply
一起使用。如果需要,使用 as.data.frame
将其转换为数据框,但由于数据完全是数字,将其作为矩阵可能就足够了。
w <- 5
thresh <- w/2
Mean <- function(x, thresh) if (sum(is.na(x)) > thresh) NaN else mean(x,na.rm=TRUE)
rollapply(df, w, Mean, thresh = thresh, fill = NA)
2) 另一种可能性是检查每个单元格中是否有超过阈值的 NA,如果是 return NaN,否则 return 滚动意思。如果需要数据框,请再次对结果使用 as.data.frame
。 (1) 比这个有优势,它只调用 roll*
一次而不是两次。
w <- 5
thresh <- w/2
ifelse(rollsum(is.na(df), w, fill = NA) > thresh, NaN,
rollmean(df, w, na.rm = TRUE, fill = NA))