根据 Group 和 ifelse 条件将 NA 分配给变量
Assign NA to a variable based on Group and ifelse condition
我正在尝试在 RAIN_15
列中分配 NA 值,如果 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
,那么它只是用 NA 替换 RAIN_15
中的值 > 100。
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]
与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
分组
- 通过查找更新连接 table
1。 if() ... else
按组
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
子句而不是像 .
中那样调用 fifelse()
函数
原因是 any()
已经是一个聚合函数,它总是 returns 一个长度为 的逻辑向量 。另外一点就是RAIN_15
的元素应该替换为相同的值NA
。 fifelse()
是一个向量函数,它逐个元素地重复决策,在这种情况下这是一种浪费。
但是,这种方法的缺点是 RAIN_15
列的 所有 元素被替换,即使对于那些根本不需要替换的组也是如此。
2。使用查找更新连接 table
这种方法只会在必要时更新行:
library(data.table)
setDT(df)[df[, which(any(RAIN_15 > 100)), by = gr], on = .(gr), RAIN_15 := NA][]
此处,df
与 查找 table 连接,其中包含需要通过引用更新的组 ID gr
。其他组将保持不变。
查找table由
创建
df[, which(any(RAIN_15 > 100)), by = gr]
gr V1
1: 17 1
它只包含满足条件的组ID。可以忽略第 V1
列。
数据
如上所述,修改后的示例数据集包括另一组的另外 2 行 testing/demonstration。
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
")
我正在尝试在 RAIN_15
列中分配 NA 值,如果 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
,那么它只是用 NA 替换 RAIN_15
中的值 > 100。
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]
与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
分组- 通过查找更新连接 table
1。 if() ... else
按组
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
子句而不是像
fifelse()
函数
原因是 any()
已经是一个聚合函数,它总是 returns 一个长度为 的逻辑向量 。另外一点就是RAIN_15
的元素应该替换为相同的值NA
。 fifelse()
是一个向量函数,它逐个元素地重复决策,在这种情况下这是一种浪费。
但是,这种方法的缺点是 RAIN_15
列的 所有 元素被替换,即使对于那些根本不需要替换的组也是如此。
2。使用查找更新连接 table
这种方法只会在必要时更新行:
library(data.table)
setDT(df)[df[, which(any(RAIN_15 > 100)), by = gr], on = .(gr), RAIN_15 := NA][]
此处,df
与 查找 table 连接,其中包含需要通过引用更新的组 ID gr
。其他组将保持不变。
查找table由
创建df[, which(any(RAIN_15 > 100)), by = gr]
gr V1 1: 17 1
它只包含满足条件的组ID。可以忽略第 V1
列。
数据
如上所述,修改后的示例数据集包括另一组的另外 2 行 testing/demonstration。
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
")