Arithmetic operation (Difference) between a vector and a Matrix in R - r

I am facing this issue when I am trying to calculate the difference between list and matrix in R, it is giving me weird results.
matrix <- matrix(1:10,1:10,nrow = 10,ncol=10)
list1 <- seq(1:10)
diff <- list1-matrix
Below is the output that I am trying to achieve but it does not work. Please let me know what I am doing wrong.

We can do this with multiple ways
1) Transpose the matrix, subtract from the vector and then do the transpose
t(t(matrix)- list1)
2) replicate the vector to make the lengths same and then do the difference
matrix - list1[col(matrix)]
3) Using sweep
sweep(matrix, 2, list1, `-`)

What you need to understand is that in R matrices are stored in column-major order. This means that a matrix is a sequence of numbers order by columns from top to down.
So when you subtract a vector from a matrix you can imagine it as operation with 4 steps:
matrix is turned into a sequence of numbers (a vector)
your "list1" is expanded (repeated) so that it's length matches the length of the vector constructed from the matrix.
the elements in each are subtracted from each other
the numbers are assembled into the matrix form again.
In your case:
1) matrix is turned into a sequence of numbers (by columns) giving you:
1, 1, 1 ,1 ... 1, 2, 2, 2, 2, ... 2, ... ... 10, 10, 10, 10, ... 10
2) Your second vector is repeated until it matches the first one:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1 ,2 ,3 ,4 ,5 ,6 ,7 ,8, 9, 10, ... 1, 2, 3, ... 10
3) Now both of them have the same length so they are subtracted from each other:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, ..., -9, -8, -7, ... 0
4) The result is transformed into a matrix again giving you the matrix that you see.
In order to obtain your desired result you have to take this into account. One way is to transpose your matrix, do the subtraction, and transpose it back again:
t(t(matrix) - list1)
This works because after the transpose t the rows are turned into columns.
Another approach is to construct a matrix out of your list1 vector:
matrix2 <- matrix(list1, nrow=10, ncol=10, byrow=TRUE)
And then do the subtraction:
diff <- matrix - matrix2

Related

Is there in R function for finding index of an array?

this is going to be a body of the particular Question.
which function we are using in array .
You can find the index of the element by the functions
which() or match()
Example for using which():
# vector created
v <- c(0, 1, 2, 3, 4,
5, 6, 7, 8, 9)
# which function is used
# to get the index
which(v == 5) # output is: 6
Example for using match():
# vector created
v <- c(0, 1, 2, 3, 4,
5, 6, 7, 8, 9)
# match function is
# used to get the index
match( 5 , v ) # output is: 6
You can see here more information
For a matrix or an array, set the argument arr.ind = TRUE:
which(myarray == 5, arr.ind = TRUE)

How to count the number of times a pattern changes?

I have a vector created simulating a continious time Markov Chain. The vector represents the path the chain may describe. Simulating 20 steps we could have:
Xt <- c(5, 5, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1, 0 ,0)
Further, the vector can jump 1 by 1 or jump from any state (5,4,3,2,1) to 0. So other simulation could be:
Xt <- c(5, 5, 5, 5, 5, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
I want to count the number of times the simulated chain jumps to other state (when the vector changes of number) within a determined interval. For example:
The number of jumps for the first vector I wrote for the first 10 elements is 2 (Jumps from 5 to 4 and 4 to 0). The number of jumps for the second vector I wrote for the last 10 elements is 0 (The last 10 elements are all 0)
So I would like to count the number of jumps (the number of times the pattern changes). I tried using toString(Xt)and then trying to match some regex but nothing worked. Any ideas?
You can use diff for this which counts the difference between adjacent numbers in a vector. Sum all instances not equal to zero to get total times the pattern changes.
First 10:
sum(diff(Xt[1:10])!=0)
[1] 2
Last 10:
sum(diff(Xt[(length(Xt)-10):length(Xt)])!=0)
[1] 0
Seems like just count the number of times the difference was not zero would deliver the desired result:
Xt <- c(5, 5, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1, 0 ,0)
sum(diff(Xt) != 0)
If the goal was to write a function that takes a string and a starting positon it could be done thusly:
jump_in_next_10 <- function(string, start){
sum( diff(string[start:(start+9)]) != 0 )}
jump_in_next_10(Xt, 3)
#[1] 2

How to only get value from data.frame in R?

i am trying to calculate the probabilities of 4 dices being thrown in R. I am nearly finished, i just want to know how i could possibly access ONLY the value in a specific row of my test1 dataframe? If i write rowSums(test1[1,]) it gives me both the index AND the sum, but i only want to access the sum to be able to store how many possibilities there are to get i.e. a 4 with 4 dices etc.
HereĀ“s the important place of the code.
wurf1 <- c(1, 2, 3, 4, 5, 6)
wurf2 <- c(1, 2, 3, 4, 5, 6)
wurf3 <- c(1, 2, 3, 4, 5, 6)
wurf4 <- c(1, 2, 3, 4, 5, 6)
test1 <- data.frame(expand.grid(wurf1, wurf2, wurf3, wurf4))
rowSums(test1[1,]) #this gives me:
1
4 #because the sum of the values in index 1 = 4
Thank you for your help in advance.

Finding n tuples from a list whose aggregation satisfies a condition

I have a list of two-element vectors. From this list, I'd like to find n vectors (not necessarily distinct) (x,y), such that the sum of the ys of these vectors is larger or equal to a number k. If multiple vectors satisfy this condition, select the one where the sum of the xs is the smallest.
For example, I'd like to find n=2 vectors (x1,y1) and (x2,y2) such that y1+y2 >= k. If there are more than just one which satisfies this condition, select the one where x1+x2 is the smallest.
I've so far only managed to set-up the following code:
X <- c(3, 2, 3, 8, 7, 7, 13, 11, 12, 12)
Y <- c(2, 1, 3, 6, 5, 6, 8, 9, 10, 9)
df <- data.frame(A, B)
l <- list()
for (i in seq(1:nrow(df))){
n <- as.numeric(df[i,])
l[[i]] <- n
}
Using the values above, let's say n=1, k=9, then I'll pick the tuple (x,y)=(11,9) because even though (12,9) also matches the condition that y=k, the x is smaller.
If n=2, k=6, then I'll pick (x1,y1)=(3,3) and (x2,y2)=(3,3) because it's the smallest x1+x2 that satisfies y1+y2 >= 6.
If n=2, k=8, then I'll pick (x1,y1)=(3,3) and (x2,y2)=(7,5) because y1+y2>=8 and in the next alternative tuples (3,3) and (8,6), 3+8=11 is larger than 3+7.
I feel like a brute-force solution would be possible: all possible n-sized combinations of each vector with the rest, for each permutation calculate yTotal=y1+y2+y3... find all yTotal combinations that satisfy yTotal>=k and of those, pick the one where xTotal=x1+x2+x3... is minimal.
I definitely struggle putting this into R-code and wonder if it's even the right choice. Thank you for your help!
First, it seems from your question that you allow to select from Y with replacement. The code basically does your brute-force approach: use the permutations in the gtools library to generate the permutations. Then basically do the filtering for sum(Y)>=k, and ordering first by smallest sum(Y) and then sum(X).
X <- c(3, 2, 3, 8, 7, 7, 13, 11, 12, 12)
Y <- c(2, 1, 3, 6, 5, 6, 8, 9, 10, 9)
n<-1
perm<-gtools::permutations(n=length(Y),r=n, repeats.allowed=T)
result<-apply(perm,1,function(x){ c(sum(Y[x]),sum(X[x])) })
dim(result) # 2 10
k=9 ## Case of n=1, k=9
keep<-which(result[1,]>=k)
result[,keep[order(result[1,keep],result[2,keep])[1]]] # 9 and 11
##### n=2 cases ##########
n<-2
perm<-gtools::permutations(n=length(Y),r=n, repeats.allowed=T)
result<-apply(perm,1,function(x){ c(sum(Y[x]),sum(X[x])) })
dim(result) # 2 100
## n=2, k=6
keep<-which(result[1,]>=6)
keep[order(result[1,keep],result[2,keep])[1]] # the 23 permutation
perm[23,] # 3 3 is (Y1,Y2)
result[,keep[order(result[1,keep],result[2,keep])[1]]] # sum(Y)=6 and sum(X)=6
## n=2, k=8
keep<-which(result[1,]>=8)
keep[order(result[1,keep],result[2,keep])[1]] # the 6 permutation
perm[6,] # 1 6 is (Y1,Y2)
result[,keep[order(result[1,keep],result[2,keep])[1]]] # sum(Y)=8 and sum(X)=10

ifelse statement in R

I'm looking at a gene in 10 people. And this gene has two alleles, say a and b. And each allele has 3 forms: type 2, 3 or 4.
a <- c(2, 2, 2, 2, 3, 3, 3, 2, 4, 3)
b <- c(4, 2, 3, 2, 4, 2, 3, 4, 4, 4)
I wish to code a variable that tells me how many type 4 alleles the person has: 0, 1, or 2.
var <- ifelse(a==4 & b==4, 2, 0)
The code above doesn't work since I didn't account for the individuals who have just one copy of the type 4 allele. I feel like I might need 2 ifelse statements that work simultaneously?
EDIT: You don't actually need ifelse or any fancy operations other than plus and equal to.
var <- (a == 4) + (b == 4)
If you're set on ifelse, this can be done with
var <- ifelse(a == 4, 1, 0) + ifelse(b == 4, 1, 0)
However, I prefer the following solution using apply. The following will give you three cases, the result being the number of 4's the person has (assuming each row is a person).
a = c(2, 2, 2, 2, 3, 3, 3, 2, 4, 3)
b = c(4, 2, 3, 2, 4, 2, 3, 4, 4, 4)
d <- cbind(a,b)
apply(d, 1, function(x) {sum(x == 4)})
For this operation, I first combined the two vectors into a matrix since it makes applying the function easier. In R, generally if data are the same type it is easier (and faster for the computer) to combine the data into a matrix/data frame/etc., then create a function to be performed on each row/column/etc.
To understand the output, consider what happens to the first row of d.
> d[1, ]
a b
2 4
> d[1, ] == 4
a b
FALSE TRUE
Booleans are interpreted as integers under addition, so
> FALSE + TRUE
[1] 1
It doesn't seem to matter whether the 4 came from a or b, so we end up with three cases: 0, 1, and 2, depending on the number of 4's.

Resources