繁体   English   中英

根据其他列的条件将数值替换为NA

[英]Replace a numerical value by NA based on conditions from other columns

这与之前的问题有关,可以在以下网址找到:

根据其他列的条件将数值替换为NA:

以下是数据:

DT <- data.table(a = sample(c("C","M","Y","K"),  100, rep=TRUE),
                   b = sample(c("A","S"),  100, rep=TRUE),
                   f = round(rnorm(n=100, mean=.90, sd=.08),digits = 2) ); DT

我希望对以下功能进行优雅而简洁的重写:

`%between%` <- function(x, vals) { x >= vals[1] & x <= vals[2]}
`%nbetween%` <- Negate(`%between%`)

和以下脚本用NA替换满足某些条件的某些值

DT[a == "C" & b %in% c("A", "S") & f %nbetween% c(.85, .95), f := NA]
DT[a == "M" & b %in% c("A", "S") & f %nbetween% c(.85, .95), f := NA]
DT[a == "Y" & b %in% c("A", "S") & f %nbetween% c(.80, .90), f := NA]
DT[a == "K" & b %in% c("A", "S") & f %nbetween% c(.95, 1.10), f := NA]

如果你矢量化你的功能,那么你可以使它更优雅:

`%between%` <- function(x, vals, vals2)  x >= vals & x <= vals2
`%nbetween%` <- Negate(`%between%`)

# This will get you a nice ranges table.
ranges<-data.table(a=c('C','M','Y','K'),low=c(0.85,0.85,0.80,0.95),high=c(0.95,0.95,0.90,1.10))
# Set the keys for an easy merge.
setkeyv(ranges,'a')
setkeyv(DT,'a')
# Merge and filter.    
DT<-merge(DT,ranges,all.x=TRUE)[b %in% c('A','S') & `%nbetween%`(f,low,high),f:=NA ]
# A nice suggestion from the comments:
DT<-DT[ranges][b %in% c('A','S') & `%nbetween%`(f,low,high),f:=NA]

#     a b    f  low high
#  1: C S 0.88 0.85 0.95
#  2: C S   NA 0.85 0.95
#  3: C S 0.92 0.85 0.95
#  4: C A 0.94 0.85 0.95
#  5: C S   NA 0.85 0.95
#  6: C S 0.90 0.85 0.95

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM