Translate matrix algebra code from VB to R - r

For a project, I am trying to replicate/rewrite the following Visual Basic code from a case study so I can run it in R.
For j=1 to N
For I=1 to M
While I>j
If b(I,j) c=P then
a(I,j)=l else
if b(1, j)<= [P+ (l-P ) /21 then
a(I,j)=3 else
a(1, j)=O
end if
end if
wend
while Icj
if a(I,j)=l then
a(j,i)=l else
if a(I,j)=3 then
a(j,I)=O else
a( j ,I) =3
end if
end if
wend
next
next
The goal is to compare the values b(j,I) from matrix B(M,N) and fill matrix A(M,N) with either 0,1 or 3. It should represent the results of a football game.
This is what I got so far:
M <- 3
N <- 3
A <- matrix(0,M,N)
B <- matrix(sample(0:4,25, replace=TRUE),nrow=M, ncol=N)
for (i in 1:nrow(B)) {
for (j in 1:ncol(B)) {
while (i > j) {
if (B[i,j] > B[j,i]) {
A[i,j] = 3 & A[j,i] = 0
}
if (B[i,j] < B[j,i]) {
A[i,j] = 0 & A[j,i] = 3
}
else {
A[i,j] = 1 & A[j,i] = 1
}
}
}
}
I would really appreciate any help or tips!

Related

Matrix multiplication with repeat loop in R

repeat_prod_mat = function(mat1,mat2){
prod = 0
repeat{
if (ncol(mat1) == ncol(mat2) & nrow(mat1) == nrow(mat2)){
prod = mat1*mat2
}
else{
break
}
}
return(prod)
}
I have to do this with repeat loop but no idea why it won't work.

Couldn't calculate prime numbers within a range

for (i in 2:100 )
{
count <- 0
for (j in i )
if( (i %% j ) == 0 )
count <- count + 1
if(count == 2 )
print(i)
}
I am trying to print print prime numbers in R. Could any one help me to resolve
Let us look at your code and show what went wrong. It's the inner loop that did not loop at all:
for (i in 2:100 )
{
count <- 0
for (j in 1:i ) # you forgot to provide a vector here
if( i %% j == 0 )
count <- count + 1
if(count == 2)
print(i)
}
The answer above tries to optimise the code some more and is a more efficient solution. For example does it only test odd numbers because even ones clearly aren't prime numbers.
The below code creates the function prime_numbers which returns prime numbers up to an inputted number.
prime_numbers <- function(n) {
if (n >= 2) {
x = seq(2, n)
prime_nums = c()
for (i in seq(2, n)) {
if (any(x == i)) {
prime_nums = c(prime_nums, i)
x = c(x[(x %% i) != 0], i)
}
}
return(prime_nums)
}
else {
stop("Input number should be at least 2.")
}
}
## return the answer to your question
prime_numbers(100)
If you wanted the range 3:100, after running the above code you could run something like this:
a<-prime_numbers(100)
a[a>3]
I hope this helps!

For statement nested in while statement not working

I am learning how to use while and for loops, and am having difficulty executing a for loop within a while loop. I am trying to recurse a simple procedure over a vector, and have the while loop set the conditionals for which parts of the vector are operated upon. This is really just meant as an exercise to understand how to use for and while loops in conjunction.
data <- c(1:200)
n=0
while(n < 100){
for(x in data){
n=x+1
if(x >= 10 & x < 100){
print("double digit")
} else {
print("single digit")
}}}
I want to stop the while loop when the procedure hits x=100 of the vector that runs from 1:200. But instead, the for loop runs through every element within the vector, from 1:200, failing to stop executing when n hits 100.
Would appreciate any advice to help out a new coder, thanks.
I have also tried
for(x in data){
n=x+1
while(n < 100){
if(x >= 10 & x < 100){
print("double digit")
} else {
print("single digit")
}}}
But the code does not stop executing.
First let's try a for loop. Each time through it n will be set to the loop counter plus 1. If this result is between 10 and 100, print a message, if not print something else. Note that no loop depends on n .
data <- c(1:200)
n = 0
for (x in data) {
n = x + 1
if (n < 100) {
if (x >= 10 && x < 100) {
print("double digit")
} else {
print("single digit")
}
}
}
x
#[1] 200
n
#[1] 201
Now for a while loop. I believe it is much simpler, it only envolves one variable, n.
n <- 0
while (n < 100) {
n = n + 1
if (n < 100) {
if (n >= 10) {
print("double digit")
} else {
print("single digit")
}
}
}
n
#[1] 100

Creating Subset of Vector Adds Null Values

I'm trying to create a mergeSort algorithm in R. While I think I have the method down, the first time I create the vector e, I end up with a vector of length 4 instead of 2. This causes the error below:
"Error in if (a[2] < a[1]) { : missing value where TRUE/FALSE needed"
For some reason, R is adding an extra 2 elements to what should be a two-element vector. If anyone has an explanation for this, that would be wonderful. (Please limit advice to solving this error. I want to figure out how to do the rest on my own.)
Code:
addLeftOver <- function(buffer, array, index) {
j <- length(buffer)
for(i in array[index:length(array)]) {
buffer[j] = i
print(i)
j <- j+1
}
return(buffer)
}
mergeSort <- function(a) {
len <- length(a)
print(a)
print(len)
browser()
if(len<=2) { #base case
if(len==1) {
return(a)
}
if(a[2]<a[1]) {
return(c(a[2],a[1]))
}
return(a)
}
print(len/2)
b <- mergeSort(a[1:(len/2)]) #recursion
e <- mergeSort(a[(len/2)+1:len]) #recursion
indexB <- 1
indexE <- 1
buffer
for(i in 1:len) {
if(e[indexC]<b[indexB]) {
buffer[index] <- e[indexE]
index <- index + 1
indexE <- indexE + 1
} else {
buffer[index] <- b[indexB]
index <- index + 1
indexB <- indexB + 1
}
if(indexB==len/2) {
buffer = addLeftover(buffer, e, indexE)
return(buffer)
}
if(indexE==len/2) {
buffer = addLeftover(buffer, b, indexB)
return(buffer)
}
}
}
sumArray <- c(6,4,2,7,8,1,3,5)
print(mergeSort(sumArray))
The addLeftOver() function's purpose is to copy the remnants of one of the two vectors (b or e) to the buffer when the end of the other has been reached.
Main error can be fixed with parenthesis. e <- mergeSort(a[(len/2)+1:len]) should be e <- mergeSort(a[((len/2)+1:len])
That and some other bugs were fixed.
Working code:
addLeftOver <- function(buffer, array, index)
{
j <- length(buffer)+1
for(i in array[index:length(array)]) {
buffer[j] = i
j <- j+1
}
return(buffer)
}
mergeSort <- function(a)
{
len <- length(a)
if(len<=2)
{
if(len==1)
{
return(a)
}
if(a[2]<a[1])
{
return(c(a[2],a[1]))
}
return(a)
}
half <- as.integer(len/2)
b <- mergeSort(a[1:(half)])
e <- mergeSort(a[((half)+1):len])
index <- 1
indexB <- 1
indexE <- 1
buffer <- c(0)
for(i in 1:len)
{
if(e[indexE]<b[indexB])
{
buffer[index] <- e[indexE]
index <- index + 1
indexE <- indexE + 1
}
else
{
buffer[index] <- b[indexB]
index <- index + 1
indexB <- indexB + 1
}
if(indexB==(length(b))+1)
{
buffer = addLeftover(buffer, e, indexE)
return(buffer)
}
if(indexE==(length(e))+1)
{
buffer = addLeftover(buffer, b, indexB)
return(buffer)
}
}
}

MATLAB to R Conversion: Append values to an existing empty array through for loop

I have the below code with me. This code was written originally in MATLAB. I have two questions here:
1) What would be the corresponding command in R for the below command in MATLAB:
duet(i).p = [];
2) In the below code I am getting all the correct 6 values for duet$n, but I am not getting correct values for duet$p. My question is how to append the values to an empty existing array duet$p[i] in R through the for loop iterations.
This line is not working in the below code:
duet$p[i] <- c(duet$p[i],j)
I might also have declared duet$p[i] <- array() incorrectly.
The values for duet.n and duet.p from MATLAB are:
duet.n
2 0 2 0 1 3
duet.p
[] [3,6] [] [1,3,5,6] [1,6] []
In R, I am getting duet$n values correctly, but I am not able to get the array kind of results for duet$p.
Any help to get the duet$p values would be appreciated.
x <- matrix(c(-1,2,4,1,7,4.2,3,0,1.2,-1.2,5.1,4,2,3.1,1.1,1,1,9,0,1,2,2,8,1,2,2,2,2,2,2),nrow=6,ncol=5,byrow=T)
fro=1;N=6;M=2;V=3;
F <- list(f=c())
duet = list()
for (i = 1 : N){
duet$n[i] = 0
duet$p[i] = array() ## Create an empty array
for (j in 1 : N){
dl = 0
de = 0
dm = 0
for (k = 1 : M){
if (x[i,V + k] < x[j,V + k]){
dl = dl + 1
} else if (x[i,V + k] == x[j,V + k]){
de = de + 1
} else{
dm = dm + 1
}
}
if (dl == 0 & de != M){
duet$n[i] = duet$n[i] + 1
} else if (dm == 0 & de != M){
duet$p[i] = c(duet$p[i],j)
}
}
if (duet$n[i] == 0){
x[i,6] = 1
F$f = c(F$f,i)
}
}
This appears to get the output you want:
x <- matrix(c(-1,2,4,1,7,4.2,3,0,1.2,-1.2,5.1,4,2,3.1,1.1,1,1,9,0,1,2,2,8,1,2,2,2,2,2,2),nrow=6,ncol=5,byrow=T)
fro=1;N=6;M=2;V=3;
F <- list(f=c())
duet = list(n=rep(0,N), p=lapply(1:N, function(x)c()))
for (i in 1 : N){
duet$n[i] = 0
#duet$p[[i]] = c() ## Create an empty array
#if(i==2) browser()
for (j in 1 : N){
k=1:M
dl <- sum(x[i,V + k] < x[j,V + k])
de <- sum(x[i,V + k] == x[j,V + k])
dm <- sum(x[i,V + k] > x[j,V + k])
if (dl == 0 & de != M){
duet$n[i] = duet$n[i] + 1
} else if (dm == 0 & de != M){
duet$p[[i]] = c(duet$p[[i]],j)
}
}
if (duet$n[i] == 0){
#x[i,6] = 1
F$f = c(F$f,i)
}
}
What have I done?
commented out the line x[i,6] =1, because there isn't an x[i,6], and I'm not sure what you meant it to be. You will need to sort this out.
Initialised duet$n as a vector
Initialised duet$p as a list of n empty vectors
removed the k loop as conditional counting in R can be done as the sum of elements where the condition is TRUE.
corrected the syntax of for loops: = became in
I think you're trying to do duet[i]$p instead of what you're doing. Also you need to initialize each cell as a list

Resources