如何在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 
    } 
}