Convert df's rows into matrices inside an array - r

I have a nxp data frame and I want to convert it to an array with n matrices where each matrix is, let's say, ixj where i+j = p. Considering the following reprex:
library(tidyverse)
df <- tribble(
~x1, ~x2, ~x3, ~x4,
1, 2, 3, 4,
5, 6, 7, 8)
The desired result is an array with 2 matrices similar to the one produced by:
array(1:8, c(2,2,2))
Would anybody have an efficient method to obtain such results in high dimensional data frames?

With baseR and array:
array(t(df), c(2, 2, 2))
#, , 1
#
# [,1] [,2]
#[1,] 1 3
#[2,] 2 4
#
#, , 2
#
# [,1] [,2]
#[1,] 5 7
#[2,] 6 8

Related

Sample without replacement x number of times from a vector

I have a vector c(1,2,3,4,5,6,7,8,9,10,11). I want to draw a sample of N = 2, 5 times from this vector without replacement; I would like to save the results from each selection in a separate column.
The output could look like this:
structure(c(1, 2, 3, 9, 7, 10, 4, 8, 5, 6), dim = c(2L, 5L)).
matrix with two rows and five columns.
matrix(sample(x), nrow=2, ncol=5)
# [,1] [,2] [,3] [,4] [,5]
# [1,] 5 7 4 8 2
# [2,] 3 10 9 1 6
Something like the following:
set.seed(7*11*13)
x <- c(1,2,3,4,5,6,7,8,9,10,11)
result <-matrix(as.numeric(NA), 2, 5)
for (i in 1:5) result[,i] <-
sample(x, 2, replace=FALSE)

Look up R matrix cells in a vectorized way

I'd like to lookup matrix cells by using rows and columns from a data frame. Preferably, I'd like to do this in a vectorized way for best performance. However, the most obvious syntax leads to a lookup of all the row-column combinations possible, not only the combinations that stem from one data frame row:
Here is a small example:
> m1 <- matrix(c(1, 2, 3, 4, 5, 6, 7, 8, 9), 3, 3)
>
> m1
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
>
> p1 <- data.frame(row = c(2, 3, 1), column = c(3, 1, 2))
>
> p1
row column
1 2 3
2 3 1
3 1 2
>
> # vectorized indexing that does not work as intended
> m1[p1$row, p1$column]
[,1] [,2] [,3]
[1,] 8 2 5
[2,] 9 3 6
[3,] 7 1 4
>
> # this works as intended, but is possible slow due to R-language looping
> sapply(1 : nrow(p1), function (i) { m1[p1[i, "row"], p1[i, "column"]] })
[1] 8 3 4
The sapply call computes the output I expect (only m1[2, 3], m1[3, 1] and m1[1, 2]), but it's expected to be slow for larger data frames because it loops in R language.
Any thoughts on a better (ideally vectorized) way?
For your intended purpose you need to use a matrix to subset the matrix using certain row,column combinations. So you can try:
m1[as.matrix(p1)]
# [1] 8 3 4
Or if you have two vectors:
m1[cbind(row_idx, col_idx)]

In R creating vector from specific matrix (dataframe) elements [duplicate]

This question already has answers here:
extracting a particular diagonal form a data frame [duplicate]
(5 answers)
Sum of antidiagonal of a matrix
(5 answers)
Closed 1 year ago.
I want to form a vector from some specific elements of matrix (or dataframe).
I would like to create vector from for example minor diagonal elements from this matrix (e.g elements matrix[3,1], matrix[2,2] and matrix [1,3]).
How could I do it without looping? My task is quite big and I would like skip looping. Following command:
matrix[c(3, 2, 1), c(1, 2, 3)]
instead of vector c(3, 5, 7) gives me another matrix.
Either of these will do what you want:
x <- matrix(1:9, 3, 3)
x
# [,1] [,2] [,3]
# [1,] 1 4 7
# [2,] 2 5 8
# [3,] 3 6 9
rc <- seq(ncol(x))
diag(x[rev(rc),])
# [1] 3 5 7
x[cbind(rev(rc), rc)]
# [1] 3 5 7
try this
mat <- matrix(1:9, nrow = 3, byrow = T)
diag(apply(mat,2,rev))
Your matrix:
mymatrix <- matrix(data= c(1,2,3,4,5,6,7,8,9), nrow = 3, byrow = T)
# [,1] [,2] [,3]
#[1,] 1 2 3
#[2,] 4 5 6
#[3,] 7 8 9
you can get the diagonal like this:
diag(mymatrix)
# [1] 1 5 9

How to compare single values of a vector with matrix and if they occur take values from another matrix with the same position?

I'm a programming beginner and I'm not able to solve this problem:
I have a vector length 132 and two matrices A and B with the size of 132x24. I would like to take every single value of the vector and compare it rowwise with matrix A. If the value occurs in A I want to have the index of the column to go to matrix B and pick the value from the column with the same position (row and column indices) as in matrix A. The results should be given back as a vector with the same length of 132.
How to do this? Do I need a for loop or are there some smart ways to work with packages?
Unfortunately I can not give example data.
Thank you for your help!
# vector v contains values that I want to compare with matrix A
> v
[1] 5 1 10 1 7
# every single value of v occurs in every row of A only once
# I want to have the position of this value in matrix A
> A
[,1] [,2] [,3] [,4]
[1,] 5 7 4 1
[2,] 14 1 3 3
[3,] 13 3 1 10
[4,] 2 1 5 8
[5,] 13 2 5 7
# the position in matrix A equals the position in matrix B
# now the values of B have to be returned as a vector
> B
[,1] [,2] [,3] [,4]
[1,] 6 3 4 3
[2,] 5 2 5 5
[3,] 4 6 3 1
[4,] 3 6 1 5
[5,] 2 4 6 3
# vector with fitting values of B
> x
[1] 6 2 1 6 3
v <- c(5, 1, 10, 1, 7)
A <- matrix(c(
5, 7, 4, 1,
14, 1, 3, 3,
13, 3, 1, 10,
2, 1, 5, 8,
13, 2, 5, 7), 5, byrow = TRUE)
B <- matrix(c(
6, 3, 4, 3,
5, 2, 5, 5,
4, 6, 3, 1,
3, 6, 1, 5,
2, 4, 6, 3), 5, byrow = TRUE)
myfun <- function(i) which(v[i]==A[i,])
ii <- 1:length(v)
B[cbind(ii, sapply(ii, myfun))]
The function myfun() is quick'n'dirty.
To test if your data are ok you can calculate how often the value v[i] is found in the row A[i,]
countv <- function(i) sum(v[i]==A[i,])
all(sapply(ii, countv)==1) ### should be TRUE
If you get FALSE then inspect:
which(sapply(ii, countv)!=1)
Alright, I'm not sure how you pictured your output, but I've got something that comes near.
Example data:
x <- 1:132
set.seed(123)
A <- matrix(sample(1:1000, size = 132*24, replace = TRUE), nrow = 132, ncol = 24)
B <- matrix(rnorm(132*24), nrow = 132, ncol = 24)
Now we check for every value of vector x if and where it occurs in every row of matrix A:
x.vs.A <- sapply(x, function(x){
apply(A, 1, function(y) {
match(x, y)
})
})
This gives us a matrix x.vs.A with 132 rows (the rows of A) and 132 columns (the values of x). Within the cells of this matrix, we will find either NA, if the combination of one value of x and one row of A was unsuccessful, or the column position within A of the FIRST match of the value of x.
And now we extract the rowwise position and bind them together with the cell value, depiting the second (column) dimension of the matched value. Thus we create for every value of x a matrix of row/column position of matches in matrix A:
x.in.A <- apply(x.vs.A, 2, function(x) cbind(which(!is.na(x)), x[!is.na(x)]))
Example:
> x.in.A[[1]]
[,1] [,2]
[1,] 12 17
[2,] 42 17
[3,] 73 12
[4,] 123 21
This would show that the first value in vector x can be found in A[12, 17], in A[42, 17] and so on.
Now access these values in B, returning vectors for each value of x, and bind them to the matrices in the list:
x.in.B <- lapply(x.in.A, function(x){
apply(x, 1, function(y){
B[y[1], y[2]]
})
})
x.in.AB <- mapply(function(x, y) cbind(x, y),
x.in.A, x.in.B)
> x.in.AB[[1]]
y
[1,] 12 17 -0.2492526
[2,] 42 17 -0.7985330
[3,] 73 12 0.1253824
[4,] 123 21 -0.9704919

Combinatorics R

I have a problem I think best can be solved using cominatorics.
Lets say you have values 4 values (2,5,6,7). I would like to get all vectors where I pick out 3 of them, that is I would like a matrix with (2,5,6),(2,5,7),(5,6,7). I would like to do this with a general vector. How do I do it?
x <- c(2, 5, 6, 7)
combn(x, 3)
gives
> combn(x, 3)
[,1] [,2] [,3] [,4]
[1,] 2 2 2 5
[2,] 5 5 6 6
[3,] 6 7 7 7
I have created a package iterpc which is able to solve most of the combination/permutation related problems.
library(iterpc)
x <- c(2, 5, 6, 7)
# combinations
getall(iterpc(4, 3, label=x))
# combinations with replacement
getall(iterpc(4, 3, replace=TRUE, label=x))
# permutations
getall(iterpc(4, 3, label=x, ordered=TRUE))

Resources