簡體   English   中英

根據 Group 和 ifelse 條件將 NA 分配給變量

[英]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 方法:

  1. if() ... else按組
  2. 使用查找表更新連接

1. if() ... else by group

library(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列的所有元素都會被替換,即使對於那些根本不需要這樣做的組也是如此。

2. 使用查找表更新連接

這種方法只會在必要時更新行:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM