我正在嘗試將 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
對于此示例,我希望所有具有 >= 3NaN
值的值都生成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
uj5u.com熱心網友回復:
1)定義一個函式,如果其輸入中有thresh
或多個 NA,則回傳 NaN,否則回傳非 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)另一種可能性是檢查每個單元格中是否有超過 thresh 的 NA,如果是則回傳 NaN,否則回傳滾動平均值。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))
uj5u.com熱心網友回復:
有了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
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/447962.html