Home > front end >  How to create a new matrix from output of another matrix using loops and functions?
How to create a new matrix from output of another matrix using loops and functions?

Time:10-13

How can I create a function points (), that takes matrix goals as input, with 2 columns and where the number of rows depend on the input of the user? The first column is for the home goals and the second column is for the away goals. How can I get the goals matrix, that the function takes a second input win_points that specifies the number of points a team receives for a win?

Points are for example, 3 points for winning, 1 for equal score, 0 if lost. So if a team wins 1-0, the win_point matrix should be displayed as 3 0, if a team plays 4-4, the win_point matrix should be displayed as 1 1 in points.

I also tried it like this, but I think with function it will work better. I used for my code now a matrix of 10 rows and 2 columns, the rows should be flexible (that you can put every amount of rows) and the columns should be 2 fixed, because there are only 2 teams in a match.

What did I do wrong in the code below?

set.seed(1)
goals1 <- matrix(sample(0:5, size = 5*2, replace = TRUE), nrow=5, ncol=2)
points1 <- matrix(0, nrow(goals1),ncol(goals1))
for(i in 1:nrow(goals1)) {
  for(j in 1:ncol(goals1)) {
    if goals1[goals1[i]>goals1[j]] {
      points1[i] <- 3
      points1[j] <- 0
    } else if goals1[goals1[i]<goals1[j]] {
      points1[i] <- 0
      points1[j] <- 3
    } else if goals1[goals1[i]==goals1[j]] {
      points1[i] <- 1
      points1[j] <- 1
    }
  }
}

First of all, thanks for the answer with the correct code! But why isn't this code above working? I do not understand what I am doing wrong in my code. CAN SOMEONE EXPLAIN PLEASE!

CodePudding user response:

You can create a simple vectorized function that takes as parameters the score matrix, the number of points for a win (defaulted to 3), and the number of points for a draw (defaulted to 1). Then, we can use the win and draw points as multipliers for logical comparisons of the scores in each match. No need for loops here.

points <- function(goals, win_points = 3, draw_points = 1)
{
  
  data.frame(home = win_points * as.numeric(goals[,1] > goals[,2])   
                    draw_points * (goals[,1] == goals[,2]),
             away = win_points * as.numeric(goals[,2] > goals[,1])   
                    draw_points * (goals[,2] == goals[,1])) |>
    as.matrix()
}

So, creating a random matrix of goals, we get:

set.seed(1)

goals <- matrix(sample(0:5, size = 10*2, replace = TRUE), nrow=10, ncol=2)
colnames(goals) <- c("Home", "Away")

goals
#>       Home Away
#>  [1,]    0    0
#>  [2,]    3    4
#>  [3,]    0    4
#>  [4,]    1    1
#>  [5,]    4    5
#>  [6,]    2    5
#>  [7,]    5    1
#>  [8,]    1    0
#>  [9,]    2    4
#> [10,]    2    4

And we can get the points matrix from the goals matrix as easily as:

points(goals)
#>       home away
#>  [1,]    1    1
#>  [2,]    0    3
#>  [3,]    0    3
#>  [4,]    1    1
#>  [5,]    0    3
#>  [6,]    0    3
#>  [7,]    3    0
#>  [8,]    3    0
#>  [9,]    0    3
#> [10,]    0    3

EDIT

If for some reason you want a loop, you need to simplify your logic and just use a single loop - since there are only two columns, you don't need to iterate through the columns, just compare column 1 to column 2 in each row. The following is a working example:

for(i in 1:nrow(goals1)) {
    if(goals1[i, 1] > goals1[i, 2]) {
      points1[i, 1] <- 3
      points1[i, 2] <- 0
    } else if (goals1[i, 1] < goals1[i, 2]) {
      points1[i, 1] <- 0
      points1[i, 2] <- 3
    } else if (goals1[i, 1] == goals1[i, 2]) {
      points1[i, 1] <- 1
      points1[i, 2] <- 1
    }
}

Created on 2021-10-12 by the reprex package (v2.0.0)

  • Related