0

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

5 回答 5

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"
于 2013-03-11T10:22:34.443 回答
2
normalize <- function(browser){
  replace(browser, !(browser %in% c("Chrome", "Firefox", "Safari") | 
                     grepl('IE',browser)), "Others")  
}
于 2013-03-11T10:33:24.577 回答
2

这里有两条评论。

最好使用||而不是|. 这就是为什么。

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

另一种方法是使用any.

 normalize = function(browser){
   if (any(browser == "Chrome", browser == "Firefox", browser == "Safari",
     grepl("IE", browser)) {
     browser
   } else {
     "Others
   }
 }
于 2013-03-11T11:34:11.927 回答
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
于 2013-03-11T10:34:47.387 回答
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"
于 2013-03-11T10:23:33.457 回答