我需要一个函数来计算不同范围的仪器测量的不确定性(例如,我测量电流,如果它在2 mA范围内,则不确定度为测量值的0.1 % + 3 dig
)。如果函数能够采用向量并返回向量而不仅仅是数字,那就更好了。
我编写了很多if
的函数,但它返回警告the condition has length > 1 and only the first element will be used
。经过一段时间的研究后,我发现R中的if
被设计为使用一个表达式来计算单个布尔值,而ifelse
可以使用向量。
但是因为大约有10个链else if
s ifelse
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))) {
...
}
...
}
ifelse
s
S.I = function(I) {
ifelse(I<=(2*10^(-6)),0.1*I/100 + 3*10^(-9),ifelse(I<=(2*10^(-6)),...,ifelse(...)))
}
在这种情况下,是否有ifelse
的替代方案?
答案 0 :(得分:3)
在R
中执行此操作的常用方法可能是cut
;这是一个例子。
## 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]
答案 1 :(得分:1)
如您所述,您的函数仅适用于单个值,因为if
不会对矢量起作用。解决方案是将向量的每个值逐个发送到函数。
R提供了一组apply
函数来完成它(它像for循环但速度更快):
result = sapply(I_vector, S.I)
如果您想在代码中多次应用S.I
向量,那么使用包装器是值得的:
wrapper_S.I = function(I) { return(sapply(I_vector, S.I)) }
result = wrapper_S.I(I_vector)
注意:您还可以使用Vectorize
创建包装器:
wrapper_S.I = Vectorize(S.I)
创建一个带有额外控件的包装器。