将条件字符串解析为R函数体

  • 本文关键字:函数体 条件 字符串 r
  • 更新时间 :
  • 英文 :


我想创建一个基于列内少量依赖关系的数据清理规则。例如,如果Q3是3,那么我需要检查Q1是否为空。我可以用这样一个简单的命令来做:

df$Q1chk<-ifelse(df$Q3==3 & is.na(df$Q1), 1,0)

,其中final Q1chk中的1表示ok。现在,由于我有很多条件和列,我希望有更灵活和优雅的解决方案。首先我要分配一个过滤器检查像这样的列:attr(df$Q1, "filter")<-"Q3==3",然后对整个数据集运行一个函数。condition可能与"=="运营商。

如何传递字符串条件"Q3==3"到函数,让它工作。我试过这样做:

ChkF<-function(dat, var) {
exp<- attr(dat[[var]], "filter")
dat[[paste0("chk",var)]]<- ifelse(is.na(dat[[var]]) & dat[eval(rlang::parse_expr(exp))==TRUE], 1 , 0)
}

但它不起作用。我知道这个表达式:dat[["Q3"]]==3工作得很好,但简单地用方括号替换引号(从"Q3==3"[["Q3"]]==3)看起来不像一个优雅的解决方案。有没有更合适的方法?最后,我想在一列中结合使用许多条件,例如:attr(df$Q1, "filter")<-c("Q3==3", "Q4>1", "Q5 %in% 2:7"),所以这就是为什么我想保持条件的语法尽可能简单的原因。

使用data.table:

library(data.table)
set.seed(1)
##
#   made up example
#
dt <- data.table(Q3=rpois(100, 3), Q4=rnorm(100, 1), Q5=rnbinom(100, mu=7, size=50))
##
#  you start here
#
filters <- lapply(c("Q3==3", "Q4>1", "Q5 %in% 2:7"), str2expression)
dt[, lapply(filters, (x) as.integer(eval(x))), by=.(Q3, Q4, Q5)]
##     Q3          Q4 Q5 V1 V2 V3
##  1:  2  1.39810588  7  0  1  1
##  2:  2  0.38797361  4  0  0  1
##  3:  3  1.34111969  7  1  1  1
##  4:  5 -0.12936310  7  0  0  1
##  5:  2  2.43302370  5  0  1  1
##  6:  5  2.98039990 10  0  1  0
##  ...

最新更新