我正在尝试制作这个操作矩阵,将第一列乘以2,3和4,第一个保持值,然后将第二列乘以3和4,保持第三列的值并乘以第三列我希望在不使用“for”循环的情况下执行此操作,希望使用sapply或mapply等函数。有没有人知道怎么做?
一行示例:
a[1,1]*(a[1,2], a[1,3], a[1,4]) = 2 4 4 4
a[1,1] a[1,2]*(a[1,3], a[1,4]) = 2 4 16 16 #keep a[1,1] a[1,2]
a[1,1] a[1,2] a[1,3] a[1,3]*(a[1,4]) = 2 4 16 256 # #keep a[1,1] a[1,2] a[1,3]
输入:
> a<- matrix(2,4,4) # or any else matrix like a<- matrix(c(1,8,10,1,4,1),3,3)
> a
[,1] [,2] [,3] [,4]
[1,] 2 2 2 2
[2,] 2 2 2 2
[3,] 2 2 2 2
[4,] 2 2 2 2
输出:
> a
[,1] [,2] [,3] [,4]
[1,] 2 4 16 256
[2,] 2 4 16 256
[3,] 2 4 16 256
[4,] 2 4 16 256
编辑:循环版本
a<- matrix(2,4,4);
ai<-a[,1,drop=F];
b<- matrix(numeric(0),nrow(a),ncol(a)-1);
i<- 1;
for ( i in 1:(ncol(a)-1)){
a<- a[,1]*a[,-1,drop=F];
b[,i]<- a[,1];
}
b<- cbind(ai[,1],b);
b
答案 0 :(得分:3)
如果我理解正确,你要做的是,从带有N列的矩阵A开始,执行以下步骤:
步骤1.将A的第2列到第A列乘以A的第1列。调用生成的矩阵A1。
步骤2.将A1的第3列到第N列乘以A1的第2列。调用生成的矩阵A2。
...
步骤(N-1)。将A(N-2)的列N乘以A(N-2)的列(N-1)。这是理想的结果。
如果这确实是你想要做的,你需要写一个双for
循环(你想要避免,如你所说)或者想出一些执行上述步骤的迭代方法
双for
方式看起来像这样
DoubleFor <- function(m) {
res <- m
for(i in 1:(ncol(res)-1)) {
for(j in (i+1):ncol(res)) {
res[, j] <- res[, i] * res[, j]
}
}
res
}
使用R的矢量化操作,可以避免内部for
循环
SingleFor <- function(m) {
res <- m
for(i in 1:(ncol(res)-1))
res[, (i+1):ncol(res)] <- res[, i] * res[, (i+1):ncol(res)]
res
}
在迭代过程时,您可能希望定义递归函数,或使用Reduce
。递归函数类似于
RecursiveFun <- function(m, i = 1) {
if (i == ncol(m)) return(m)
n <- ncol(m)
m[, (i+1):n] <- m[, (i+1):n] * m[, i]
Recall(m, i + 1) # Thanks to @batiste for suggesting using Recall()!
}
虽然Reduce
将使用类似的函数而没有递归(由Reduce
提供)
ReduceFun <- function(m) {
Reduce(function(i, m) {
n <- ncol(m)
m[, (i+1):n] <- m[, (i+1):n] * m[, i]
m
}, c((ncol(m)-1):1, list(m)), right = T)
}
这些都会产生相同的结果,例如:测试你的矩阵
a <- matrix(c(1, 8, 10, 1, 4, 1), 3, 3)
DoubleFor(a)
# [,1] [,2] [,3]
# [1,] 1 1 1
# [2,] 8 32 2048
# [3,] 10 10 1000
all(DoubleFor(a) == SingleFor(a) & SingleFor(a) == RecursiveFun(a) &
RecursiveFun(a) == ReduceFun(a))
# [1] TRUE
出于好奇,我做了一个快速的速度比较,但我不认为上面的任何一个会比你的其他任何一个明显快于你的矩阵大小,所以我会选择你那个认为更具可读性。
a <- matrix(rnorm(1e6), ncol = 1e3)
system.time(DoubleFor(a))
# user system elapsed
# 22.158 0.012 22.220
system.time(SingleFor(a))
# user system elapsed
# 27.349 0.004 27.415
system.time(RecursiveFun(a))
# user system elapsed
# 25.150 1.336 26.534
system.time(ReduceFun(a))
# user system elapsed
# 26.574 0.004 26.626