2017-01-31 37 views
1

获得不等式表达式(字符)的上限和下限的正确方法是什么?这里是一个例子:将不等式表达式(字符)解析为数字范围

df = structure(list(expressions = c("x<1", "x>1", "x==1", "x<=1", 
"x>=1")), .Names = "expressions", class = "data.frame", row.names = c(NA, 
-5L)) 

我的输入是df$expressions。我想获得df$minimumdf$maximum像下面

expressions minimum maximum 
1   x<1  NA 0.99999 
2   x>1 1.00001  NA 
3  x==1 1.00000 1.00000 
4  x<=1  NA 1.00000 
5  x>=1 1.00000  NA 

当只有<,从数中减去1e-5。当只有>时,将1e-5添加到数字中。

+0

为什么不写一个函数,不等式表达式作为字符输入和'x'作为数字输入?正如你所说,'gsub'和'if ... else'完成了这个诀窍。 – ottlngr

+0

你说过:“只有<时,从数字中减去1e-5。” - 所以有一个数字。必须有一个数字减去1e-5 ... – ottlngr

+0

哦,对不起,现在我明白了。当然,“数字”是1。无论如何,一个简单的函数应该做到这一点。 – ottlngr

回答

1
#FUNCTION 
foo = function(eq, delta = 1e-5){ 
    #Extract the numerical portion of the expression 
    n = as.numeric(gsub("\\D+", "", eq)) 

    #Create vector x 
    x = c(-Inf, n - delta, n, n + delta, Inf) 

    #Evaluate eq by plugging in x and subset values of x where TRUE 
    y = x[eval(expr = parse(text = eq))] 

    return(range(y)) 
} 

t(sapply(df$expressions, foo)) 
#  [,1] [,2] 
#x<1  -Inf 0.99999 
#x>1 1.00001  Inf 
#x==1 1.00000 1.00000 
#x<=1 -Inf 1.00000 
#x>=1 1.00000  Inf 
1

完全不同的方法可能不符合您的要求。 但我想如果最终的目标是在实际数据上使用范围,您实际上也可以选择这种方法。

如果不是,这是值得尝试:

library(dplyr) 

expressions = c('x < 1','x > 1','x == 1','x <= 1','x >= 1') 

df <- data.frame(x = seq(0,2,by=1e-05)) 

df %>% mutate_(.dots=setNames(expressions, seq_along(expressions))) %>% 
    gather(key,value, -x) %>% mutate(u = ifelse(value,x,NA)) %>% 
    group_by(key) %>% summarise(minimum = min(u, na.rm=T), maximum = max(u, na.rm=T)) %>% 
    mutate(key = factor(key, labels=expressions)) 

结果:

# A tibble: 5 × 3 
    key minimum maximum 
    <fctr> <dbl> <dbl> 
1 x < 1 0.00000 0.99999 
2 x > 1 1.00001 2.00000 
3 x == 1 1.00000 1.00000 
4 x <= 1 0.00000 1.00000 
5 x >= 1 1.00000 2.00000