如何在R中矢量化我的函数?
问题描述:
我在R中编写函数如下,但我不能以向量化的方式使用它(下面的代码的第二部分)。我想知道我怎样才能使这个功能矢量化如何在R中矢量化我的函数?
normalize=function(browser){
if (browser=="Chrome" | browser=="Firefox" | browser=='Safari' | grepl('IE',browser)){
browser
}else{
"Others"
}
}
data$browser_n<-normalize(data$browser) // not working (data is a data frame)
答
虽然这可能不是最正确的答案,你可以试试Vectorize
。通常,您可以在许多函数上使用Vectorize
来对它们进行矢量化。我要补充一点,Vectorize
只是围绕mapply
normalize = function(browser) {
if (browser == "Chrome" | browser == "Firefox" | browser == "Safari" | grepl("IE", browser)) {
return(browser)
} else {
return("Others")
}
}
vNormalize <- Vectorize(normalize)
data <- data.frame(browser = c("Chrome", "Firefox", "Safari", "IE 10"))
vNormalize(data$browser)
## [1] Chrome Firefox Safari IE 10
## Levels: Chrome Firefox IE 10 Safari
答
使用ifelse():
normalize=function(browser){
ifelse(browser=="Chrome" | browser=="Firefox" | browser=='Safari' | grepl('IE',browser), browser, 'Others')
}
browser <- c('aaa', 'Chrome')
normalize(browser)
# [1] "Others" "Chrome"
答
或者,如果你是不是在矢量很感兴趣,但想获得新的变量browser_n
在你的榜样,你可以只写
data$browser_n<-data$browser
data$browser_n[!(data$browser=="Chrome" | data$browser=="Firefox" |
data$browser=='Safari' | grepl('IE',data$browser))] <- "Others"
答
normalize <- function(browser){
replace(browser, !(browser %in% c("Chrome", "Firefox", "Safari") |
grepl('IE',browser)), "Others")
}
答
一个漂亮的包装这里有两点意见。
使用||
而不是|
会更好。这是为什么。
&和& &表示逻辑与和|和||表示逻辑或。较短的形式以与算术运算符几乎相同的方式执行元素比较。较长的形式从左到右进行评估,仅检查每个矢量的第一个元素。评估只会在结果确定之前进行。更长的形式适用于编程控制流程,并且通常优先考虑if子句。
另一种方法是使用any
。
normalize = function(browser){
if (any(browser == "Chrome", browser == "Firefox", browser == "Safari",
grepl("IE", browser)) {
browser
} else {
"Others
}
}