在 R 中的两个矩阵之间切换行
Switch rows between two matrices in R
设矩阵A和B。
A=c(1:5)*matrix(1,5,5)
B=10*A
即
> A
[,1] [,2] [,3] [,4] [,5]
[1,] 1 1 1 1 1
[2,] 2 2 2 2 2
[3,] 3 3 3 3 3
[4,] 4 4 4 4 4
[5,] 5 5 5 5 5
> B
[,1] [,2] [,3] [,4] [,5]
[1,] 10 10 10 10 10
[2,] 20 20 20 20 20
[3,] 30 30 30 30 30
[4,] 40 40 40 40 40
[5,] 50 50 50 50 50
例如,我想在矩阵A和B之间切换第一行,即
> A
[,1] [,2] [,3] [,4] [,5]
[1,] 10 10 10 10 10
[2,] 2 2 2 2 2
[3,] 3 3 3 3 3
[4,] 4 4 4 4 4
[5,] 5 5 5 5 5
> B
[,1] [,2] [,3] [,4] [,5]
[1,] 1 1 1 1 1
[2,] 20 20 20 20 20
[3,] 30 30 30 30 30
[4,] 40 40 40 40 40
[5,] 50 50 50 50 50
使用函数,不使用任何中间向量或 for
循环。
replace
似乎没有任何中间件就可以工作
replace(A, cbind(1, 1:ncol(A)), B[1,])
replace(B, cbind(1, 1:ncol(A)), A[1,])
请注意,一旦我们对原始对象进行赋值,第二次赋值是不可能的,因为原始对象已更改
一种干净的交换方法是创建一个临时对象,rm
它
tmp <- A[1,]
A[1, ] <- B[1, ]
B[1, ] <- tmp
rm(tmp)
gc()
或者可能创建一个函数,在函数内部进行交换,这样一旦退出函数就会删除激活记录(因为这些是按值传递的)
f1 <- function(a, b) {
t1 <- a[1,]
a[1,] <- b[1,]
b[1,] <- t1
return(list(a, b))
}
list2env(setNames(f1(A, B), c('A', 'B')), .GlobalEnv)
更新
根据您在评论中的更新,您可以试试
lapply(
1:nrow(B),
function(k) {
setNames(
Map(
function(x, ind,r) {
x[ind, ] <- r
x
},
list(A, B),
list(1,k),
list(B[k, ], A[1, ])
), c("A", "B")
)
}
)
这给出了
[[1]]
[[1]]$A
[,1] [,2] [,3] [,4] [,5]
[1,] 10 10 10 10 10
[2,] 2 2 2 2 2
[3,] 3 3 3 3 3
[4,] 4 4 4 4 4
[5,] 5 5 5 5 5
[[1]]$B
[,1] [,2] [,3] [,4] [,5]
[1,] 1 1 1 1 1
[2,] 20 20 20 20 20
[3,] 30 30 30 30 30
[4,] 40 40 40 40 40
[5,] 50 50 50 50 50
[[2]]
[[2]]$A
[,1] [,2] [,3] [,4] [,5]
[1,] 20 20 20 20 20
[2,] 2 2 2 2 2
[3,] 3 3 3 3 3
[4,] 4 4 4 4 4
[5,] 5 5 5 5 5
[[2]]$B
[,1] [,2] [,3] [,4] [,5]
[1,] 10 10 10 10 10
[2,] 1 1 1 1 1
[3,] 30 30 30 30 30
[4,] 40 40 40 40 40
[5,] 50 50 50 50 50
[[3]]
[[3]]$A
[,1] [,2] [,3] [,4] [,5]
[1,] 30 30 30 30 30
[2,] 2 2 2 2 2
[3,] 3 3 3 3 3
[4,] 4 4 4 4 4
[5,] 5 5 5 5 5
[[3]]$B
[,1] [,2] [,3] [,4] [,5]
[1,] 10 10 10 10 10
[2,] 20 20 20 20 20
[3,] 1 1 1 1 1
[4,] 40 40 40 40 40
[5,] 50 50 50 50 50
[[4]]
[[4]]$A
[,1] [,2] [,3] [,4] [,5]
[1,] 40 40 40 40 40
[2,] 2 2 2 2 2
[3,] 3 3 3 3 3
[4,] 4 4 4 4 4
[5,] 5 5 5 5 5
[[4]]$B
[,1] [,2] [,3] [,4] [,5]
[1,] 10 10 10 10 10
[2,] 20 20 20 20 20
[3,] 30 30 30 30 30
[4,] 1 1 1 1 1
[5,] 50 50 50 50 50
[[5]]
[[5]]$A
[,1] [,2] [,3] [,4] [,5]
[1,] 50 50 50 50 50
[2,] 2 2 2 2 2
[3,] 3 3 3 3 3
[4,] 4 4 4 4 4
[5,] 5 5 5 5 5
[[5]]$B
[,1] [,2] [,3] [,4] [,5]
[1,] 10 10 10 10 10
[2,] 20 20 20 20 20
[3,] 30 30 30 30 30
[4,] 40 40 40 40 40
[5,] 1 1 1 1 1
您可以试试下面的代码
list2env(
setNames(
Map(
function(x, r) {
x[1, ] <- r
x
},
list(A, B),
list(B[1, ], A[1, ])
), c("A", "B")
),
envir = .GlobalEnv
)
设矩阵A和B。
A=c(1:5)*matrix(1,5,5)
B=10*A
即
> A
[,1] [,2] [,3] [,4] [,5]
[1,] 1 1 1 1 1
[2,] 2 2 2 2 2
[3,] 3 3 3 3 3
[4,] 4 4 4 4 4
[5,] 5 5 5 5 5
> B
[,1] [,2] [,3] [,4] [,5]
[1,] 10 10 10 10 10
[2,] 20 20 20 20 20
[3,] 30 30 30 30 30
[4,] 40 40 40 40 40
[5,] 50 50 50 50 50
例如,我想在矩阵A和B之间切换第一行,即
> A
[,1] [,2] [,3] [,4] [,5]
[1,] 10 10 10 10 10
[2,] 2 2 2 2 2
[3,] 3 3 3 3 3
[4,] 4 4 4 4 4
[5,] 5 5 5 5 5
> B
[,1] [,2] [,3] [,4] [,5]
[1,] 1 1 1 1 1
[2,] 20 20 20 20 20
[3,] 30 30 30 30 30
[4,] 40 40 40 40 40
[5,] 50 50 50 50 50
使用函数,不使用任何中间向量或 for
循环。
replace
似乎没有任何中间件就可以工作
replace(A, cbind(1, 1:ncol(A)), B[1,])
replace(B, cbind(1, 1:ncol(A)), A[1,])
请注意,一旦我们对原始对象进行赋值,第二次赋值是不可能的,因为原始对象已更改
一种干净的交换方法是创建一个临时对象,rm
它
tmp <- A[1,]
A[1, ] <- B[1, ]
B[1, ] <- tmp
rm(tmp)
gc()
或者可能创建一个函数,在函数内部进行交换,这样一旦退出函数就会删除激活记录(因为这些是按值传递的)
f1 <- function(a, b) {
t1 <- a[1,]
a[1,] <- b[1,]
b[1,] <- t1
return(list(a, b))
}
list2env(setNames(f1(A, B), c('A', 'B')), .GlobalEnv)
更新
根据您在评论中的更新,您可以试试
lapply(
1:nrow(B),
function(k) {
setNames(
Map(
function(x, ind,r) {
x[ind, ] <- r
x
},
list(A, B),
list(1,k),
list(B[k, ], A[1, ])
), c("A", "B")
)
}
)
这给出了
[[1]]
[[1]]$A
[,1] [,2] [,3] [,4] [,5]
[1,] 10 10 10 10 10
[2,] 2 2 2 2 2
[3,] 3 3 3 3 3
[4,] 4 4 4 4 4
[5,] 5 5 5 5 5
[[1]]$B
[,1] [,2] [,3] [,4] [,5]
[1,] 1 1 1 1 1
[2,] 20 20 20 20 20
[3,] 30 30 30 30 30
[4,] 40 40 40 40 40
[5,] 50 50 50 50 50
[[2]]
[[2]]$A
[,1] [,2] [,3] [,4] [,5]
[1,] 20 20 20 20 20
[2,] 2 2 2 2 2
[3,] 3 3 3 3 3
[4,] 4 4 4 4 4
[5,] 5 5 5 5 5
[[2]]$B
[,1] [,2] [,3] [,4] [,5]
[1,] 10 10 10 10 10
[2,] 1 1 1 1 1
[3,] 30 30 30 30 30
[4,] 40 40 40 40 40
[5,] 50 50 50 50 50
[[3]]
[[3]]$A
[,1] [,2] [,3] [,4] [,5]
[1,] 30 30 30 30 30
[2,] 2 2 2 2 2
[3,] 3 3 3 3 3
[4,] 4 4 4 4 4
[5,] 5 5 5 5 5
[[3]]$B
[,1] [,2] [,3] [,4] [,5]
[1,] 10 10 10 10 10
[2,] 20 20 20 20 20
[3,] 1 1 1 1 1
[4,] 40 40 40 40 40
[5,] 50 50 50 50 50
[[4]]
[[4]]$A
[,1] [,2] [,3] [,4] [,5]
[1,] 40 40 40 40 40
[2,] 2 2 2 2 2
[3,] 3 3 3 3 3
[4,] 4 4 4 4 4
[5,] 5 5 5 5 5
[[4]]$B
[,1] [,2] [,3] [,4] [,5]
[1,] 10 10 10 10 10
[2,] 20 20 20 20 20
[3,] 30 30 30 30 30
[4,] 1 1 1 1 1
[5,] 50 50 50 50 50
[[5]]
[[5]]$A
[,1] [,2] [,3] [,4] [,5]
[1,] 50 50 50 50 50
[2,] 2 2 2 2 2
[3,] 3 3 3 3 3
[4,] 4 4 4 4 4
[5,] 5 5 5 5 5
[[5]]$B
[,1] [,2] [,3] [,4] [,5]
[1,] 10 10 10 10 10
[2,] 20 20 20 20 20
[3,] 30 30 30 30 30
[4,] 40 40 40 40 40
[5,] 1 1 1 1 1
您可以试试下面的代码
list2env(
setNames(
Map(
function(x, r) {
x[1, ] <- r
x
},
list(A, B),
list(B[1, ], A[1, ])
), c("A", "B")
),
envir = .GlobalEnv
)