这应该是非常简单的,但即使在检查了所有文档和在线示例后,我也没有得到它。
我想使用switch()来替换字符向量的值。
一个假的,极其简单,可重复的例子:
test<-c("He is", "She has", "He has", "She is")
假设我想将“1”包括动词“to be”和“2”分配给句子,包括动词“to have”。以下不起作用:
test<-switch(test,
"He is"=1,
"She is"=1,
"He has"=2,
"She has"=2)
错误信息:
+ + + + Error in switch(test, `He is` = 1, `She is` = 1, `He has` = 2, `She has` = 2) :
EXPR must be a length 1 vector
我认为EXPR确实是长度为1的向量,所以有什么不对?
我认为可能是R期望的字符作为替换,但是既没有将switch()包装成“as.integer”也没有包含以下工作:
test<-switch(test,
"He is"="1",
"She is"="1",
"He has"="2",
"She has"="2")
也许它没有矢量化,我应该做一个循环?是吗?考虑到R的强度是矢量化,会令人失望。提前致谢!
矢量化形式的if
是ifelse
:
test <- ifelse(test == "He is", 1,
ifelse(test == "She is", 1,
ifelse(test == "He has", 2,
2)))
要么
test <- ifelse(test %in% c("He is", "She is"), 1, 2)
switch
基本上是一种编写嵌套if
-else
测试的方法。您应该将if
和switch
视为控制流语句,而不是数据转换运算符。您可以使用它们来控制算法的执行,例如测试收敛或选择要执行的执行路径。在大多数情况下,您不会使用它们直接操作数据。
这是矢量化函数的正确方法,例如,开关:
# Data vector:
test <- c("He is",
"She has",
"He has",
"She is")
# Vectorized SWITCH:
foo <- Vectorize(vectorize.args = "a",
FUN = function(a) {
switch(as.character(a),
"He is" = 1,
"She is" = 1,
"He has" = 2,
2)})
# Result:
foo(a = test)
He is She has He has She is
1 2 2 1
我希望这有帮助。
你可以试试
test_out <- sapply(seq_along(test), function(x) switch(test[x],
"He is"=1,
"She is"=1,
"He has"=2,
"She has"=2))
或者等价
test_out <- sapply(test, switch,
"He is"=1,
"She is"=1,
"He has"=2,
"She has"=2)
我发现这种方法最具可读性:
# input
test <-c("He is", "She has", "He has", "She is", "Unknown", "She is")
# mapping
map <- c(
"He is" = 1,
"She has" = 2,
"He has" = 2,
"She is" = 1)
answer <- map[test]
# output
answer
He is She has He has She is <NA> She is
1 2 2 1 NA 1
如果test
是数字,必须将值转换为character
才能使用它。
虽然我通常更喜欢基本R方法,但有一个带矢量化开关功能的包。
library(broman)
switchv(c("horse", "fish", "cat", "bug"),
horse="fast",
cat="cute",
"what?")
根据评论添加使用OP数据。
library(broman)
test<-c("He is", "She has", "He has", "She is")
test<-switchv(test,
"He is"="1",
"She is"="1",
"He has"="2",
"She has"="2")
test
“Vectorize”基于“mapply”函数,而“ifelse”是应该已经向量化的基函数。因此,在性能方面,“Vectorize”可能会更慢。使用'apply'系列很容易对R函数进行矢量化,但性能通常是大容量的问题。最好使用优化的基本函数来处理向量。
这是来自recode()
的car
的解决方案:
# Data vector:
x <- c("He is", "She has", "He has", "She is")
library("car")
recode(x, "'He is'=1; 'She is'=1; 'He has'=2; 'She has'=2") # or
recode(x, "c('He is', 'She is')=1; c('He has', 'She has')=2")