粘贴n * n矩阵或数据框的所有可能的对角线 [英] Paste all possible diagonals of an n*n matrix or dataframe
问题描述
例如,考虑以下3个X 3矩阵:
#创建矩阵,转换为字符数据帧
matrix< - matrix(data = c('s' ,'t','y','a','e','l','f','n','e'),nrow = 3,ncol = 3)
matrix< as.data.frame(matrix)
for(i in 1:length(colnames(matrix))){
matrix [,i]< - as.character(matrix [,i])
}
在上面的矩阵中,我需要粘贴对角线:see,fey ,ees和yef。我可以在数据框中找到以下代码:
diag< - paste(matrix [1,1] [2,2]矩阵[3,3],sep ='')
diag1< - paste(matrix [1,3],matrix [2,2],matrix [3,1],sep ='')
diag2< - paste(matrix [3,1],matrix [2,2],matrix [1,3],sep ='')
diag3< - paste矩阵[3,3],矩阵[2,2],矩阵[1,1],sep ='')
问题是我想自动化这个,以便它可以在任何N×N矩阵上工作。 (我正在写一个函数来找到任何N×N矩阵中的对角线)。有没有一个有效的方法来实现?
哦,这很容易,如果你使用矩阵而不是data.frame :)
我们可以选择矩阵元素,就像我们可以使用矢量元素:
矩阵[1:3]#前三个元素==第一列
n< - ncol(matrix)
(1:n-1)* n + 1:n
## [1] 1 5 9
(1:n-1)* n + n:1
## [1] 3 5 7
所以现在我们可以使用这个:
矩阵[(1:n-1)* n + 1 :n]
[1]see
paste0(matrix [(1:n-1)* n + 1:n],collapse =)
[1]看到
如果你想向后退,只需使用 rev
function:
paste0(matrix [rev((1:n -1)* n + 1:n)],collapse =)
[1]ees
一些基准:
rotate< - function(x)t(apply(x,2,rev ))
revMat< - function(mat,dir = 0){
x < if(bitwAnd(dir,1))rev(seq(nrow(mat)))else seq(nrow(mat))
y< - if(bitwAnd(dir,2))rev )))else seq(nrow(mat))
mat [x,y]
}
bartek< - function(matrix){
n < ncol(matrix)
c(paste0(matrix [(1:n-1)* n + 1:n],collapse =),paste0(matrix [rev((1:n-1) 1:n)],collapse =),
paste0(matrix [(1:n-1)* n + n:1],collapse =),paste0(matrix [rev n-1)* n + n:1)],collapse =))
}
Joe< - function(matrix){
diag0 < (矩阵)
diag1< - diag(rotate(matrix))
diag2 < - rev(diag0)
diag3< - rev(diag1)
c(paste ,collapse =),paste(diag1,collapse =),
paste(diag2,collapse =),paste(diag3,collapse =))
}
James< - function(mat){
sapply(0:3,function(x)paste(diag(revMat(mat,x)),collapse =))
}
矩阵矩阵(c('s','t','y','a','e','l','f','n' '),ncol = 3)
microbenchmark(bartek(matrix),Joe(matrix),James(matrix))
单位:微秒
expr min lq平均值uq max neval
bartek )50.273 55.2595 60.78952 59.4390 62.438 134.880 100
乔(矩阵)167.431 176.6170 188.46908 182.8260 192.646 337.717 100
詹姆斯(矩阵)321.313 334.3350 346.15230 339.7235 348.565 447.115 100
矩阵矩阵(1:10000,ncol = 100)
微基准(bartek(矩阵),乔(矩阵),詹姆斯(矩阵))
单位:微秒
expr min lq mean中位数uq max neval
bartek(矩阵)314.385 326.752 336.1194 331.936 337.9805 423.323 100
Joe(矩阵)2168.141 2221.477 2460.1002 2257.439 2298.4400 8856.482 100
詹姆斯(矩阵)1200.572 1250.354 1407.5943 1276.307 1323.8845 7419.931 100
I'm trying to paste all possible characters that are arranged in any diagonal within an N * N matrix.
For example, consider the following 3 X 3 matrix:
#Create matrix, convert to character dataframe
matrix <- matrix(data=c('s','t','y','a','e','l','f','n','e'),nrow=3,ncol=3)
matrix <- as.data.frame(matrix)
for(i in 1:length(colnames(matrix))){
matrix[,i] <- as.character(matrix[,i])
}
In the matrix above I need to paste the diagonals: "see","fey", "ees", and "yef". I can find these in the dataframe with the following code:
diag <- paste(matrix[1,1],matrix[2,2],matrix[3,3],sep='')
diag1 <- paste(matrix[1,3],matrix[2,2],matrix[3,1],sep='')
diag2 <- paste(matrix[3,1],matrix[2,2],matrix[1,3],sep='')
diag3 <- paste(matrix[3,3],matrix[2,2],matrix[1,1],sep='')
The problem is that I want to automate this so that it will work on any N x N matrix. (I'm writing a function to find the diagonals in any N X N matrix). Is there an efficient way to do this?
Oh, that's easy if you use matrix instead of data.frame :) We can choose matrix elements just like we can take vector elements:
matrix[1:3] # First three elements == first column
n <- ncol(matrix)
(1:n-1)*n+1:n
## [1] 1 5 9
(1:n-1)*n+n:1
## [1] 3 5 7
So now we can use this:
matrix[(1:n-1)*n+1:n]
[1] "s" "e" "e"
paste0(matrix[(1:n-1)*n+1:n],collapse="")
[1] "see"
And if you want it backwards, just reverse the vector of indexes using rev
function:
paste0(matrix[rev((1:n-1)*n+1:n)],collapse="")
[1] "ees"
Some benchmarks:
rotate <- function(x) t(apply(x, 2, rev))
revMat <- function(mat, dir=0){
x <- if(bitwAnd(dir,1)) rev(seq(nrow(mat))) else seq(nrow(mat))
y <- if(bitwAnd(dir,2)) rev(seq(ncol(mat))) else seq(nrow(mat))
mat[x,y]
}
bartek <- function(matrix){
n <- ncol(matrix)
c(paste0(matrix[(1:n-1)*n+1:n],collapse=""), paste0(matrix[rev((1:n-1)*n+1:n)],collapse=""),
paste0(matrix[(1:n-1)*n+n:1],collapse=""), paste0(matrix[rev((1:n-1)*n+n:1)],collapse=""))
}
Joe <- function(matrix){
diag0 <- diag(matrix)
diag1 <- diag(rotate(matrix))
diag2 <- rev(diag0)
diag3 <- rev(diag1)
c(paste(diag0, collapse = ""),paste(diag1, collapse = ""),
paste(diag2, collapse = ""),paste(diag3, collapse = ""))
}
James <- function(mat){
sapply(0:3,function(x) paste(diag(revMat(mat,x)),collapse=""))
}
matrix <- matrix(c('s','t','y','a','e','l','f','n','e'), ncol = 3)
microbenchmark(bartek(matrix), Joe(matrix), James(matrix))
Unit: microseconds
expr min lq mean median uq max neval
bartek(matrix) 50.273 55.2595 60.78952 59.4390 62.438 134.880 100
Joe(matrix) 167.431 176.6170 188.46908 182.8260 192.646 337.717 100
James(matrix) 321.313 334.3350 346.15230 339.7235 348.565 447.115 100
matrix <- matrix(1:10000, ncol=100)
microbenchmark(bartek(matrix), Joe(matrix), James(matrix))
Unit: microseconds
expr min lq mean median uq max neval
bartek(matrix) 314.385 326.752 336.1194 331.936 337.9805 423.323 100
Joe(matrix) 2168.141 2221.477 2460.1002 2257.439 2298.4400 8856.482 100
James(matrix) 1200.572 1250.354 1407.5943 1276.307 1323.8845 7419.931 100
这篇关于粘贴n * n矩阵或数据框的所有可能的对角线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!