简体   繁体   English

R中嵌套ifelse()语句的替代方法

[英]Alternative to nested ifelse() statements in R

Problem 问题

I need a function which computes uncertainty of measurement by an instrument for different ranges (eg. I measure electrical current and if it's in the range of 2 mA the uncertainty is 0.1 % + 3 dig of the measured value). 我需要一个函数来计算仪器在不同范围内的测量不确定度(例如,我测量电流,如果电流在2 mA范围内,则不确定度为测量值的0.1 % + 3 dig取值)。 It is better if the function is able to take a vector and return a vector instead of just numbers. 如果函数能够接受一个向量并返回一个向量,而不只是数字,则更好。

I have written the function with lots of if s but it returns warnings the condition has length > 1 and only the first element will be used . 我用很多if编写了函数,但是它返回警告the condition has length > 1 and only the first element will be used After a while of research I have discovered that if s in R are designed to work with an expression which evaluates to a single boolean value while ifelse can work with vectors. 一会儿的研究后,我们已经发现, if R中s的设计有其评估为单个布尔值的表达式在旅行时工作ifelse可以与载体工作。

But as there are about ten chained else if s the same thing with ifelse s would be rather ugly. 但是, else if大约有十个链结在一起, else ififelse与s进行相同的处理将非常难看。

Example

with if s: if s:

S.I = function(I) {
   if(I<=(2*10^(-6))){
      0.1*I/100 + 3*10^(-9)
   } else if(I<=(20*10^(-6))) {
      ...
   }
   ...
}

with ifelse s ifelse s

S.I = function(I) {
   ifelse(I<=(2*10^(-6)),0.1*I/100 + 3*10^(-9),ifelse(I<=(2*10^(-6)),...,ifelse(...)))
}

Question

Is there an alternative to ifelse s in this case? 在这种情况下,是否可以替代ifelse

The usual way of doing this in R is probably cut ; R中执行此操作的通常方法可能cut here's an example. 这是一个例子。

## some sample current values
I <- c(1e-6, 2e-6, 1e-5, 2e-5, 1e-4, 2e-4, 1e-3, 2e-3)
## define the endpoints for the different ranges
breaks <- c(-Inf, 2*10^(-6:3))
## for each range, define the percent of the original
## and the amount to add
percent <- c(0.10, 0.11, 0.12, 0.13)
dig <- c(3e-9, 3e-8, 3e-7, 3e-6) 
## get the range that each value falls in
range <- cut(I, breaks, labels=FALSE)
## and multiply by the right percent and add the right extra amount
I*percent[range]/100 + dig[range]

As you noted, your function only works with single values as if does not act on vectors. 如前所述,函数仅对单个值起作用,就if对向量不起作用一样。 The solution is to send each value of your vector one by one to the function. 解决方案是将向量的每个值一个一个地发送到函数。

R provides a set of apply function to do exactly that (it's like a for loop but faster) : R提供了一组apply函数来精确地做到这一点(就像for循环,但速度更快):

result = sapply(I_vector, S.I)

If you want to apply SI several times in your code on vectors, it can be worth using a wrapper : 如果要在向量的向量上多次应用SI ,那么值得使用包装器:

wrapper_S.I = function(I) { return(sapply(I_vector, S.I)) }
result = wrapper_S.I(I_vector)

NOTE: You can also create the wrapper with Vectorize : 注意:您也可以使用Vectorize创建包装器:

wrapper_S.I = Vectorize(S.I)

which creates a wrapper with extra controls. 这会创建带有额外控件的包装器。

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

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