Ken*_*ams 19 r switch-statement
我有一些R代码看起来基本上是这样的:
compute.quantiles <- function(mu, type) {
## 'mu' and 'type' are vectors of the same length
var <- ifelse(type=='a', 6.3523 * mu^2,
ifelse(type=='b', 234.23 * mu,
ifelse(type=='c', {s <- 9.8 * ((mu-0.3)/3)^(6/7)+0.19; mu + mu^2/s},
ifelse(type=='d', 56.345 * mu^1.5,
ifelse(type=='e', 0.238986 * mu^2,
ifelse(type=='f', mu + 1.1868823 * mu^2,
NA ))))))
# ...then do something with var...
}
Run Code Online (Sandbox Code Playgroud)
一些示例输入和输出:
print(compute.quantiles(2:4, c('c','d','e')))
[1] 2.643840 292.777208 3.823776
Run Code Online (Sandbox Code Playgroud)
这样做是正确的,但是深层嵌套有点难看,所以我想知道是否有更好的成语.有人有建议吗?如果switch()接受一个向量作为它的第一个参数,那将很好地工作,但它只需要一个标量.
我想我想出了一些我更喜欢的东西:
## Vector-switch
vswitch <- function(EXPR, ...) {
vars <- cbind(...)
vars[cbind(seq_along(EXPR), match(EXPR, names(list(...))))]
}
compute.quantiles <- function(mu, type) {
stopifnot(length(mu) == length(type))
vswitch( type,
a = 6.3523 * mu^2,
b = 234.23 * mu,
c = mu + mu^2/(9.8 * ((mu-0.3)/3)^(6/7)+0.19),
d = 56.345 * mu^1.5,
e = 0.238986 * mu^2,
f = mu + 1.1868823 * mu^2)
}
Run Code Online (Sandbox Code Playgroud)
使用矩阵索引代码只需2行,我认为这对我太聪明的代码阈值是可以的.=)
这是另一种方法:
library(data.table)
# Case selection table:
dtswitch <- data.table(type=letters[1:6],
result=c("6.3523 * mu^2",
"234.23 * mu",
"{s <- 9.8 * ((mu-0.3)/3)^(6/7)+0.19; mu + mu^2/s}",
"56.345 * mu^1.5",
"0.238986 * mu^2",
"mu + 1.1868823 * mu^2"),
key="type")
# Data to which you want the cases applied:
compute <- data.table(type=letters[3:5],mu=2:4,key="type")
# Join the data table with the case selection table, and evaluate the results:
dtswitch[compute,list(mu,result=eval(parse(text=result)))]
#> type mu result
#>1: c 2 2.643840
#>2: d 3 292.777208
#>3: e 4 3.823776
Run Code Online (Sandbox Code Playgroud)
不用用R代码创建dtswitch表,您可以将其存储在外部电子表格或数据库中,然后将其加载到R中。如果您有很多不同的情况或者它们经常变化并且想要从中控制它们,则可能会很方便中心位置。