当我不得不链ifelse语句,它看起来像:聪明的方式链ifelse语句?
ifelse(input=="x","x1",
ifelse(input=="y","x2",
ifelse(input=="z","x3",NA)))
有没有一种更聪明的办法做到这一点?我正在考虑创建表格然后合并或者只是为了使代码看起来更好?
当我不得不链ifelse语句,它看起来像:聪明的方式链ifelse语句?
ifelse(input=="x","x1",
ifelse(input=="y","x2",
ifelse(input=="z","x3",NA)))
有没有一种更聪明的办法做到这一点?我正在考虑创建表格然后合并或者只是为了使代码看起来更好?
除了在注释中,你也可以通过以下方式使用match
。
创建示例数据:
set.seed(1)
vals_in <- c("x", "y", "z") # unique values in your input vector
vec_in <- sample(vals_in, 10, replace = TRUE) # sample from vals_in to create input
vals_out <- c("x1", "x2", "x3") # values to replace
现在,替换的嵌套ifelse
是你可以做:
vec_out <- vals_out[match(vec_in, vals_in)]
结果是
vec_out
# [1] "x1" "x2" "x2" "x3" "x1" "x3" "x3" "x2" "x2" "x1"
一点比较两种方法:
set.seed(1)
vals_in <- letters
vec_in <- sample(vals_in, 1e7, replace = TRUE)
vals_out <- LETTERS
system.time(vals_out[match(vec_in, vals_in)])
User System verstrichen
0.378 0.020 0.398
system.time(unname(setNames(vals_out, vals_in)[vec_in]))
User System verstrichen
1.020 0.062 1.084
你可以尝试这样的函数之一:
choice <- function(input) {
switch(input,
"x"="x1",
"y"="x2",
"z"="x3",
NA)
}
#> choice("x")
#[1] "x1"
#> choice("z")
#[1] "x3"
#> choice("other")
#[1] NA
@docendodiscimus可以把这个函数包装成'sapply()'来处理一个输入向量,像这样:'sapply(my_vector,choice)',但是我认为这不会产生非常快的性能。 – RHertel
另一种办法是使用setNames
unname(setNames(vals_out, vals_in)[vec_in])
#[1] "x1" "x2" "x2" "x3" "x1" "x3" "x3" "x2" "x2" "x1"
注:摘自@docendo discimus后的例子。
使用一个已命名的向量或列表,或查看'switch'或'factor'。 – A5C1D2H2I1M1N2O1R2T1
我发现多个ifelse链更具可读性如果您不缩进每个新的ifelse,而是在',NA)))'之前添加换行符, – Pekka
我会建议使用表格,但最简单的'ifelse'语句。使得它更容易调试,并在未来明白。 – Hugh