如何在R中向量化我的函数?

时间:2013-03-11 10:18:09

标签: r function

我在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) 

5 个答案:

答案 0 :(得分:3)

使用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"

答案 1 :(得分:2)

normalize <- function(browser){
  replace(browser, !(browser %in% c("Chrome", "Firefox", "Safari") | 
                     grepl('IE',browser)), "Others")  
}

答案 2 :(得分:2)

以下是两条评论。

最好使用||代替|。这就是原因。

  

&安培;和&amp;&amp;表示逻辑AND和|和||表示逻辑OR。较短的形式以与算术运算符大致相同的方式执行元素比较。较长的形式从左到右评估仅检查每个向量的第一个元素。评估仅在确定结果之前进行。较长的形式适用于编程控制流程,通常在if子句中是首选。

另一种方法是使用any

 normalize = function(browser){
   if (any(browser == "Chrome", browser == "Firefox", browser == "Safari",
     grepl("IE", browser)) {
     browser
   } else {
     "Others
   }
 }

答案 3 :(得分:1)

虽然这可能不是最正确的答案,但您可以尝试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

答案 4 :(得分:0)

或者,如果您对矢量化不是很感兴趣,但想要在示例中获得新变量browser_n,则可以编写

data$browser_n<-data$browser
data$browser_n[!(data$browser=="Chrome" | data$browser=="Firefox" | 
               data$browser=='Safari' | grepl('IE',data$browser))] <- "Others"