r - R if/else 在函数中
问题描述
我正在尝试让以下函数用于处理属性,但我无法让 if elseif 在函数中工作。它给出了以下错误:“条件长度> 1,仅使用第一个元素”。我希望有人可以提出解决方案或替代方案。
例子:
x <- data.frame(runif(100, 0, 100))
colnames(x) <- "test"
WINSORIZE <- function(x){
WIN_MEAN <- mean(x)
WIN_SD <- sd(x)
WIN_UPPER <- sum(WIN_MEAN + (3 * WIN_SD))
WIN_LOWER <- sum(WIN_MEAN - (3 * WIN_SD))
if(x > WIN_UPPER){
WIN_UPPER
} else if (x < WIN_LOWER) {WIN_LOWER
} else x
}
WINSORIZE(x$test)
解决方案
解决方案
使用 R 的内在矢量化能力。通过分配选择[
并更改值。<-
这个解决方案非常R
-ish:
winsorize <- function(x) {
m <- mean(x)
s <- sd(x)
u <- m + 3 * s
l <- m - 3 * s
x[ x > u ] <- u # select elements > u and assign to them u in situ
x[ x < l ] <- l # select elements < l and assign to them l in situ
x # return the resulting vector
}
而且这个解决方案非常R
适合已经矢量化的ifelse()
函数:
winsorize <- function(x) {
m <- mean(x)
s <- sd(x)
u <- m + 3 * s
l <- m - 3 * s
ifelse( x > u, u, ifelse( x < l, l, x))
}
解决方案sapply()
另一种可能性是使用sapply(x, ...)
将 if-else 构造应用于 x 的每个元素。
winsorize <- function(x){
m <- mean(x)
s <- sd(x)
upper <- m + 3 * s
lower <- m - 3 * s
# apply your if-else construct on each individual element (el) of x
# using `sapply()`
sapply(x, function(el) if(el > upper){
upper
} else if (el < lower) {
lower
} else {
el})
}
或与以下内容相同ifelse()
:
winsorize <- function(x){
m <- mean(x)
s <- sd(x)
upper <- m + 3 * s
lower <- m - 3 * s
sapply(x, function(el)
ifelse(el > upper, upper, ifelse(el < lower, lower, el))
}
解决方案Vectorize()
或者从你的构造中创建一个函数,在你应用它之前if-else
使用这个函数向量化它:Vectorize()
x
winsorize <- function(x){
m <- mean(x)
s <- sd(x)
upper <- m + 3 * s
lower <- m - 3 * s
# define function for one element
winsorize.one.element <- function(el) {
if(el > upper){ upper } else if (el < lower) { lower } else { el}
}
# Vectorize this function
winsorize.elements <- Vectorize(winsorize.one.element)
# Apply the vectorized function to the vector and return the result
winsorize.elements(x)
}
这个winsorize.one.element
函数可以写得更整洁ifelse
,但是虽然ifelse
是矢量化的
推荐阅读
- swift - 如何在 swift 中围绕 Alamofire.authenticate 方法制作登录异步函数包装器?
- python - 从 Python 中的微积分函数绘制速度和距离
- windows - Perl Windows 服务 - 只运行一次
- javascript - React Native - 通过 index.js 导入多个类时出错
- node.js - 从 Node JS 读取 Telegram 频道
- jquery - Jquery 不能在联系表 7 之外工作
- mysql - 使用 Django Rest 框架的 Mysql 多连接性能
- python - 如何将从s3下载的wav文件保存到文件中
- ruby-on-rails - `rails s -p` 命令没有被 docker 捕获
- php - 嵌入式表单 - Symfony 4