我在编写apply()时遇到了问题,这个问题很慢.我的任务是在不使用apply()的情况下给出Matrix的行范围.我正在努力,但我仍然需要帮助......
这是我到目前为止所得到的:
row.range <- function(X){ Y <- matrix(0, nrow = nrow(X), ncol = 2) for(i in nrow(X)){ Y[i, 1] <- min(X[i, ]) Y[i, 2] <- max(X[i, ]) } return(Y) print(Y) }
其中X可以是任何数字矩阵.可悲的是,输出只有0,除了我实际得到正确的最小值和最大值的最后一行.为什么这只适用于最后一行?
为了测试我用过:
M <- matrix(sample(1:6, size = 100 * 5, replace = TRUE), ncol = 5) row.range(X)
任何帮助将非常感谢:-)
使用较小的可重复示例
set.seed(123) M <- matrix(sample(1:6, size = 10 * 5, replace = TRUE), ncol = 5)
您可以尝试已经完全优化的matrixStats::rowRanges
功能
matrixStats::rowRanges(M) # [,1] [,2] # [1,] 1 6 # [2,] 3 6 # [3,] 3 5 # [4,] 3 6 # [5,] 1 6 # [6,] 1 6 # [7,] 2 5 # [8,] 1 6 # [9,] 2 4 # [10,] 1 6
或者基本R矢量化max.col
函数
cbind(M[cbind(1:nrow(M), max.col(-M))], M[cbind(1:nrow(M), max.col(M))]) # [,1] [,2] # [1,] 1 6 # [2,] 3 6 # [3,] 3 5 # [4,] 3 6 # [5,] 1 6 # [6,] 1 6 # [7,] 2 5 # [8,] 1 6 # [9,] 2 4 # [10,] 1 6
另一个半矢量化基础R使用它pmin/pmax
结合do.call
(也提供可能的NA
处理),但这需要将矩阵转换为data.frame
(不推荐)
DF <- as.data.frame(M) cbind(do.call(pmin.int, c(na.rm = TRUE, DF)), do.call(pmax.int, c(na.rm = TRUE, DF))) # [,1] [,2] # [1,] 1 6 # [2,] 3 6 # [3,] 3 5 # [4,] 3 6 # [5,] 1 6 # [6,] 1 6 # [7,] 2 5 # [8,] 1 6 # [9,] 2 4 # [10,] 1 6
由于R是矢量化语言,因此行操作通常很慢,因此要么尝试向量化,要么使用诸如Rcpp之类的包来编写已编译的C/C++循环(如第一种情况中所做的那样)
在大多数激进的情况下,您仍然希望使用编译器包大大优化您的循环
至于你的for
循环(正如@PereG已经提到的那样)你有一个语法错误.而不for(i in nrow(X))
应该这样for(i in 1:nrow(X))
.否则,您只在最后一行操作.