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))
Related
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)
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)]
This question already has answers here:
Add each element in one vector with each element in a second vector
(3 answers)
Closed 4 years ago.
I have 2 vectors of different sizes:
vector1 = [1, 2, 3]
vector2 = [1, 2, 3, 4, 5]
I want to make operations between them. Each number from the vector1 plus each number from the vector2. Something like that:
I'm trying unsuccessfully a for inside a for. Any help?
vector1 <- data.frame(c(1, 2, 3))
vector2 <- data.frame(c(1, 2, 3, 4, 5))
for (i in vector1) {
for (j in vector2) {
a <- i + j
}
}
This is the message error
Warning message:
In i + j : longer object length is not a multiple of shorter object length
You can use outer
> vector1 <- c(1, 2, 3)
> vector2 <- c(1, 2, 3, 4, 5)
> outer(vector1, vector2, FUN="+")
[,1] [,2] [,3] [,4] [,5]
[1,] 2 3 4 5 6
[2,] 3 4 5 6 7
[3,] 4 5 6 7 8
If you really want to use a loop, you can use a nested for loop:
> result <- matrix(0, nrow = length(vector1), ncol=length(vector2))
> for(i in seq_len(length(vector1))){
for(j in seq_len(length(vector2))){
result[i,j] <- sum(vector1[i], vector2[j])
}
}
> result
[,1] [,2] [,3] [,4] [,5]
[1,] 2 3 4 5 6
[2,] 3 4 5 6 7
[3,] 4 5 6 7 8
for is a very inefficient way to do this. Here's a way using sapply from base R although I feel there should be an even better way -
c(sapply(vector1, function(x) x + vector2))
# [1] 2 3 4 5 6 3 4 5 6 7 4 5 6 7 8
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
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