如何避免循环遍历行和列以提高 R 中的速度
How to avoid looping over rows and columns to increase speed in R
我是 R 的新用户,第一份工作需要使用该软件。我试着在网站上寻找与我类似的问题,但没有找到。抱歉,如果我的问题是多余的。
我遇到的问题是我需要编辑每一列中的离群值。下面是一个可重现的例子:
data_X <- matrix(data = rep(1,100), nrow = 10, ncol = 10)
for (i in 1:nrow(data_x)) {
for (j in 1:ncol(data_x)) {
if (is.na(data_x[i,j])) {
data_x[i,j] <- NA
} else if (data_x[i,j]>(quantile(data_x[[j]], 0.75, na.rm=T)+1.5*(quantile(data_x[[j]], 0.75,na.rm=T)-quantile(data_x[[j]], 0.25,na.rm=T)))) {
data_x[i,j]=(quantile(data_x[[j]], 0.5, na.rm=T))
} else if (data_x[i,j]<(quantile(data_x[[j]], 0.25, na.rm=T)-1.5*(quantile(data_x[[j]], 0.75, na.rm=T)-quantile(data_x[[j]], 0.25, na.rm=T)))) {
data_x[i,j]=(quantile(data_x[[j]], 0.5, na.rm=T))
} else {
data_x[i,j]=data_x[i,j]
}
}
}
实际上,矩阵的维度要大得多,循环遍历代码大约需要4分钟。这对我来说太长了,我想知道是否有更优雅的方式。
我做了一些研究,显然 apply() 不会提高速度...
编辑:
规则:
高于 75% 分位数的数据点 + 1.5 * 四分位数分布;
和
低于 25% 分位数的数据点 - 1.5 * 分位数分布;
均转换为中位数。
1.We 创建一个规则函数,我们在其中使用向量化 ifelse
.
rule_function <- function(x) {
q25 <- quantile(x, 0.25, na.rm = TRUE)
q75 <- quantile(x, 0.75, na.rm = TRUE)
iqr <- q75 - q25
lower <- q25 - 1.5 * iqr
upper <- q75 + 1.5 * iqr
result <- ifelse(x < lower | x > upper, median(x, na.rm = TRUE), x)
return(result)
}
2.And 然后我们将函数应用于矩阵的每一列:
apply(data_X, 2, rule_function)
示例数据实际上不允许测试,所以我不能 100% 确定这是否对您有帮助。但是,对于 10000 x 10000 矩阵,这只需要几秒钟(是否 好 取决于您的实际用例;)
我是 R 的新用户,第一份工作需要使用该软件。我试着在网站上寻找与我类似的问题,但没有找到。抱歉,如果我的问题是多余的。
我遇到的问题是我需要编辑每一列中的离群值。下面是一个可重现的例子:
data_X <- matrix(data = rep(1,100), nrow = 10, ncol = 10)
for (i in 1:nrow(data_x)) {
for (j in 1:ncol(data_x)) {
if (is.na(data_x[i,j])) {
data_x[i,j] <- NA
} else if (data_x[i,j]>(quantile(data_x[[j]], 0.75, na.rm=T)+1.5*(quantile(data_x[[j]], 0.75,na.rm=T)-quantile(data_x[[j]], 0.25,na.rm=T)))) {
data_x[i,j]=(quantile(data_x[[j]], 0.5, na.rm=T))
} else if (data_x[i,j]<(quantile(data_x[[j]], 0.25, na.rm=T)-1.5*(quantile(data_x[[j]], 0.75, na.rm=T)-quantile(data_x[[j]], 0.25, na.rm=T)))) {
data_x[i,j]=(quantile(data_x[[j]], 0.5, na.rm=T))
} else {
data_x[i,j]=data_x[i,j]
}
}
}
实际上,矩阵的维度要大得多,循环遍历代码大约需要4分钟。这对我来说太长了,我想知道是否有更优雅的方式。
我做了一些研究,显然 apply() 不会提高速度...
编辑:
规则:
高于 75% 分位数的数据点 + 1.5 * 四分位数分布;
和
低于 25% 分位数的数据点 - 1.5 * 分位数分布;
均转换为中位数。
1.We 创建一个规则函数,我们在其中使用向量化 ifelse
.
rule_function <- function(x) {
q25 <- quantile(x, 0.25, na.rm = TRUE)
q75 <- quantile(x, 0.75, na.rm = TRUE)
iqr <- q75 - q25
lower <- q25 - 1.5 * iqr
upper <- q75 + 1.5 * iqr
result <- ifelse(x < lower | x > upper, median(x, na.rm = TRUE), x)
return(result)
}
2.And 然后我们将函数应用于矩阵的每一列:
apply(data_X, 2, rule_function)
示例数据实际上不允许测试,所以我不能 100% 确定这是否对您有帮助。但是,对于 10000 x 10000 矩阵,这只需要几秒钟(是否 好 取决于您的实际用例;)