I have a matrix X
:
one two three four
[1,] 1 3 2 4
[2,] 2 0 1 5
[3,] 3 2 1 4
[4,] 4 9 11 19
[5,] 4 3 2 1
I want to get a new matrix Y
which only contains rows that are permutations of "1", "2", "3", "4". That is:
one two three four
[1,] 1 3 2 4
[3,] 3 2 1 4
[5,] 4 3 2 1
What function or command should I use?
CodePudding user response:
mat <- rbind(
c(1, 3, 2, 4),
c(2, 0, 1, 5),
c(3, 2, 1, 4)
)
ok <- apply(mat, 1L, function(x) setequal(x, c(1, 2, 3, 4)))
mat[ok, ]
CodePudding user response:
Here is another approach:
library(dplyr)
library(stringr)
library(tibble)
new_matrix <- df_matrix %>%
as_tibble() %>%
filter(if_all(everything(), ~ str_detect(., paste(1:4, collapse = "|")))) %>%
as.matrix()
one two three four
[1,] 1 3 2 4
[2,] 3 2 1 4
[3,] 4 3 2 1
CodePudding user response:
X <- structure(c(1, 2, 3, 4, 4, 3, 0, 2, 9, 3, 2, 1, 1, 11, 2, 4, 5, 4, 19, 1),
dim = 5:4)
A fully vectorized base R approach:
X[.rowSums(X %in% 1:4, nrow(X), ncol(X)) == 4, ]
# [,1] [,2] [,3] [,4]
#[1,] 1 3 2 4
#[2,] 3 2 1 4
#[3,] 4 3 2 1
In general, given a target vector v
, we do
## keep rows that are permutations of `v`
X[.rowSums(X %in% v, nrow(X), ncol(X)) == length(v), ]
## remove rows that are permutations of `v`
X[.rowSums(X %in% v, nrow(X), ncol(X)) < length(v), ]
CodePudding user response:
Using pure for loop
ans <- data.frame(matrix(NA , ncol = ncol(X)))
r <- 1
for(i in 1:nrow(X)){
if(all((unique(X[i,]) %in% 1:4) & length(unique(X[i,])) == 4)){
ans[r,] <- X[i,]
r <- r 1
}
}
ans <- as.matrix(ans)
- output
X1 X2 X3 X4
1 1 3 2 4
2 3 2 1 4
3 4 3 2 1
- data
X <- matrix(c(1, 2, 3, 4, 4, 3, 0, 2, 9, 3, 2, 1, 1, 11, 2, 4,
5, 4, 19, 1) , ncol = 4)
Another option is using Filter
function
t(Filter(\(x) all((unique(x) %in% 1:4) & length(unique(x)) == 4) ,
data.frame(t(X))))