[英]Assign NA to a variable based on Group and ifelse condition
我正在嘗試在RAIN_15
RAIN_15
的任何行的值 > 100 ,則與RAIN_15
中的gr
對應的所有觀察值都將被NA
替換。 樣本數據如下:
TRGCODE RAIN DATE TIME gr RAIN_15
6155 0.0 2015-06-18 0000 17 0.0
6155 0.0 2015-06-18 0015 17 0.0
6155 0.0 2015-06-18 0030 17 0.0
6155 0.0 2015-06-18 0045 17 0.0
6155 0.0 2015-06-18 0100 17 0.0
6155 0.0 2015-06-18 0115 17 0.0
6155 0.0 2015-06-18 0130 17 0.0
6155 0.0 2015-06-18 0145 17 0.0
6155 0.0 2015-06-18 0200 17 0.0
6155 0.0 2015-06-18 0215 17 0.0
6155 0.0 2015-06-18 0230 17 0.0
6155 0.0 2015-06-18 0245 17 0.0
6155 0.2 2015-06-18 0300 17 0.2
6155 123.7 2015-06-18 0315 17 123.5
6155 127.0 2015-06-18 0330 17 3.3
6155 127.0 2015-06-18 0345 17 0.0
6155 127.0 2015-06-18 0400 17 0.0
6155 127.0 2015-06-18 0415 17 0.0
6155 127.0 2015-06-18 0430 17 0.0
6155 127.0 2015-06-18 0445 17 0.0
6155 127.0 2015-06-18 0500 17 0.0
6155 141.7 2015-06-18 0515 17 14.7
6155 594.3 2015-06-18 0530 17 452.6
6155 NA 2015-06-18 0545 17 NA
6155 NA 2015-06-18 0600 17 NA
數據有數千個這樣的行,其中gr
基於TIME
分組。 這里RAIN_15
的值 > 100,因此RAIN_15
中對應於gr
17 的所有觀察值都應替換為NA
。 我試過了
df_v1 <- df %>% group_by(TRGCODE, gr) %>% mutate(RAIN_15 = ifelse(any(RAIN_15 > 100), NA, RAIN_15))
但它正在用 0 替換 RAIN_15 值。如果我在ifelse
中刪除any
值,那么它只是將RAIN_15
中的值 > 100 替換為 NA。
使用data.table
:
library(data.table)
setDT(df_v1)
df_v1[,RAIN_15:=fifelse(rep(any(RAIN_15>100,na.rm=T),.N),NA_real_,RAIN_15),by=gr][]
TRGCODE RAIN DATE TIME gr RAIN_15
1: 6155 0.0 2015-06-18 0 17 NA
2: 6155 0.0 2015-06-18 15 17 NA
3: 6155 0.0 2015-06-18 30 17 NA
4: 6155 0.0 2015-06-18 45 17 NA
5: 6155 0.0 2015-06-18 100 17 NA
6: 6155 0.0 2015-06-18 115 17 NA
7: 6155 0.0 2015-06-18 130 17 NA
8: 6155 0.0 2015-06-18 145 17 NA
9: 6155 0.0 2015-06-18 200 17 NA
10: 6155 0.0 2015-06-18 215 17 NA
11: 6155 0.0 2015-06-18 230 17 NA
12: 6155 0.0 2015-06-18 245 17 NA
13: 6155 0.2 2015-06-18 300 17 NA
14: 6155 123.7 2015-06-18 315 17 NA
15: 6155 127.0 2015-06-18 330 17 NA
16: 6155 127.0 2015-06-18 345 17 NA
17: 6155 127.0 2015-06-18 400 17 NA
18: 6155 127.0 2015-06-18 415 17 NA
19: 6155 127.0 2015-06-18 430 17 NA
20: 6155 127.0 2015-06-18 445 17 NA
21: 6155 127.0 2015-06-18 500 17 NA
22: 6155 141.7 2015-06-18 515 17 NA
23: 6155 594.3 2015-06-18 530 17 NA
24: 6155 NA 2015-06-18 545 17 NA
25: 6155 NA 2015-06-18 600 17 NA
TRGCODE RAIN DATE TIME gr RAIN_15
為了完整起見,這里有兩種 data.table 方法:
if() ... else
按組if() ... else
by grouplibrary(data.table)
setDT(df)[, RAIN_15 := if (any(RAIN_15 > 100)) NA else RAIN_15, by = gr][]
TRGCODE RAIN DATE TIME gr RAIN_15 1: 6155 0.0 2015-06-18 0 17 NA 2: 6155 0.0 2015-06-18 15 17 NA 3: 6155 0.0 2015-06-18 30 17 NA 4: 6155 0.0 2015-06-18 45 17 NA 5: 6155 0.0 2015-06-18 100 17 NA ... 20: 6155 127.0 2015-06-18 445 17 NA 21: 6155 127.0 2015-06-18 500 17 NA 22: 6155 141.7 2015-06-18 515 17 NA 23: 6155 594.3 2015-06-18 530 17 NA 24: 6155 NA 2015-06-18 545 17 NA 25: 6155 NA 2015-06-18 600 17 NA 26: 6155 0.0 2015-06-18 0 18 0 27: 6155 0.0 2015-06-18 15 18 0 TRGCODE RAIN DATE TIME gr RAIN_15
請注意,我使用了經過修改的示例數據集和一個附加組(第 26、27 行)進行測試。
這種方法使用if() ... else
子句,而不是像waldi 的 answer那樣調用fifelse()
函數。
原因是any()
已經是一個聚合函數,它總是返回一個長度為 one的邏輯向量。 另一點是RAIN_15
的元素應該替換為相同的值NA
。 fifelse()
是一個向量函數,它逐個元素地重復決策,在這種情況下是一種浪費。
然而,這種方法的缺點是RAIN_15
列的所有元素都會被替換,即使對於那些根本不需要這樣做的組也是如此。
這種方法只會在必要時更新行:
library(data.table)
setDT(df)[df[, which(any(RAIN_15 > 100)), by = gr], on = .(gr), RAIN_15 := NA][]
在這里, df
與一個查找表連接,其中包含需要通過引用更新的組 id gr
。 其他組將保持不變。
查找表由
df[, which(any(RAIN_15 > 100)), by = gr]
gr V1 1: 17 1
它僅包含滿足條件的組 ID。 V1
列可以忽略。
如上所述,修改后的樣本數據集包括另外 2 行的另一組用於測試/演示。
library(data.table)
df <- fread("
TRGCODE RAIN DATE TIME gr RAIN_15
6155 0.0 2015-06-18 0000 17 0.0
6155 0.0 2015-06-18 0015 17 0.0
6155 0.0 2015-06-18 0030 17 0.0
6155 0.0 2015-06-18 0045 17 0.0
6155 0.0 2015-06-18 0100 17 0.0
6155 0.0 2015-06-18 0115 17 0.0
6155 0.0 2015-06-18 0130 17 0.0
6155 0.0 2015-06-18 0145 17 0.0
6155 0.0 2015-06-18 0200 17 0.0
6155 0.0 2015-06-18 0215 17 0.0
6155 0.0 2015-06-18 0230 17 0.0
6155 0.0 2015-06-18 0245 17 0.0
6155 0.2 2015-06-18 0300 17 0.2
6155 123.7 2015-06-18 0315 17 123.5
6155 127.0 2015-06-18 0330 17 3.3
6155 127.0 2015-06-18 0345 17 0.0
6155 127.0 2015-06-18 0400 17 0.0
6155 127.0 2015-06-18 0415 17 0.0
6155 127.0 2015-06-18 0430 17 0.0
6155 127.0 2015-06-18 0445 17 0.0
6155 127.0 2015-06-18 0500 17 0.0
6155 141.7 2015-06-18 0515 17 14.7
6155 594.3 2015-06-18 0530 17 452.6
6155 NA 2015-06-18 0545 17 NA
6155 NA 2015-06-18 0600 17 NA
6155 0.0 2015-06-18 0000 18 0.0
6155 0.0 2015-06-18 0015 18 0.0
")
df <- read.table(header = TRUE, text = 'TRGCODE RAIN DATE TIME gr RAIN_15
6155 0.0 2015-06-18 0000 17 0.0
6155 0.0 2015-06-18 0015 17 0.0
6155 0.0 2015-06-18 0030 17 0.0
6155 0.0 2015-06-18 0045 17 0.0
6155 0.0 2015-06-18 0100 17 0.0
6155 0.0 2015-06-18 0115 17 0.0
6155 0.0 2015-06-18 0130 17 0.0
6155 0.0 2015-06-18 0145 17 0.0
6155 0.0 2015-06-18 0200 17 0.0
6155 0.0 2015-06-18 0215 17 0.0
6155 0.0 2015-06-18 0230 17 0.0
6155 0.0 2015-06-18 0245 17 0.0
6155 0.2 2015-06-18 0300 17 0.2
6155 123.7 2015-06-18 0315 17 123.5
6155 127.0 2015-06-18 0330 17 3.3
6155 127.0 2015-06-18 0345 17 0.0
6155 127.0 2015-06-18 0400 17 0.0
6155 127.0 2015-06-18 0415 17 0.0
6155 127.0 2015-06-18 0430 17 0.0
6155 127.0 2015-06-18 0445 17 0.0
6155 127.0 2015-06-18 0500 17 0.0
6155 141.7 2015-06-18 0515 17 14.7
6155 594.3 2015-06-18 0530 17 452.6
6155 NA 2015-06-18 0545 17 NA
6155 NA 2015-06-18 0600 17 NA')
x=aggregate(RAIN_15 ~ gr, data = df, max)
x$RAIN_15=ifelse(x$RAIN_15>100, NA,x$RAIN_15)
df$RAIN_15=merge(df,x, all.x = TRUE, by="gr")[7]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.