Home > other >  R looping matrix elements
R looping matrix elements

Time:11-22

I'm trying to loop over matrix columns.

date <- rbind("2000-01-01", "2000-01-02", "2000-01-03", "2000-01-04", "2000-01-05", "2000-01-06", "2000-01-07", "2000-01-08", "2000-01-09", "2000-01-10", "2000-01-11", "2000-01-12")
a1 <- rbind("0", "0", "0", "0", "6421", "41", "5667", "44", "1178", "0", "1070", "1")
b1 <- rbind("1", "1", "1", "1", "6421", "41", "5667", "44", "1178", "0", "1070", "1")
hb1 <- rbind("2", "2", "2", "2", "6421", "41", "5667", "44", "1178", "0", "1070", "1")
a2 <- rbind("0", "0", "0", "0", "6421", "41", "5667", "44", "1178", "0", "1070", "1")
b2 <- rbind("1", "1", "1", "1", "6421", "41", "5667", "44", "1178", "0", "1070", "1")
hb2 <- rbind("2", "2", "2", "2", "6421", "41", "5667", "44", "1178", "0", "1070", "1")
a3 <- rbind("0", "0", "0", "0", "6421", "41", "5667", "44", "1178", "0", "1070", "1")
b3 <- rbind("1", "1", "1", "1", "6421", "41", "5667", "44", "1178", "0", "1070", "1")
hb3 <- rbind("2", "2", "2", "2", "6421", "41", "5667", "44", "1178", "0", "1070", "1")
a4 <- rbind("0", "0", "0", "0", "6421", "41", "5667", "44", "1178", "0", "1070", "1")
b4 <- rbind("1", "1", "1", "1", "6421", "41", "5667", "44", "1178", "0", "1070", "1")
hb4 <- rbind("2", "2", "2", "2", "6421", "41", "5667", "44", "1178", "0", "1070", "1")
info_mat <- cbind(date, a1, b1, hb1, a2, b2, hb2, a3, b3, hb3, a4, b4, hb4)
print(info_mat)

I want to compute an evolution rate (V 1 - V)/V between the months for each variable (evolution from January to Feb, Feb to March, ..., for a1, ..., hb4) and get the result in a matrix that I will name "evolution_matrix"

I tried the following but for some reason it won't work. Note that i represents here the fact that I want to perform the evolution for every variable. I think of i as being: Evolution(January to February for variable a1) = (value of a1 in February - value of a1 in January)/(value of a1 in January).

I don't know how to model it therefore I put i, but it doesn't refer to anything in the matrix.

  for(row in 1:nrow(info_mat)) {
    for(col in 1:ncol(info_mat)) {
      evolution[[i]] = (info_mat[i 1] - info_mat[i] )/info_mat[i]
    print(evolution[[i]])
    }
  }

Help please!

CodePudding user response:

Why do you use matrix? You have only character (string) variables in matrix, but you want to use them as numbers. I think data.frame is good idea.
R package dplyr has function lapply which can apply your function to each column and simplify the result by list. But we don't want to apply 'evolution' function for column date.

evolution <- as.data.frame(info_mat)[, -1] %>% 
    lapply(function(x) {x = as.numeric(x); (x - lag(x)) / lag(x)}) %>% 
    as.data.frame()

In the last line I convert list to data.frame (for beautiful printing).
But we forgot about 'date' column. Let's add it into our data.frame.

evolution <- bind_cols(data.frame(date = date), evolution)

That is all. But if you want to do it by loop you can use this code:

evolution <- matrix(NA, nrow(info_mat), ncol(info_mat))
evolution[, 1] <- date
for(row in 2:nrow(info_mat)) {
    for(col in 2:ncol(info_mat)) {
        evolution[row, col] = as.numeric(info_mat[row, col])/as.numeric(info_mat[row - 1, col]) - 1
    }
}

Comments about your example of code:

  1. you have no variable i and don't use variables row and col.
  2. what is the type of evolution variable?
  3. info_mat[i 1] is not numeric. You cannot divide it on info_mat[i].
  4. What does info_mat[i] means? Yes, info_mat[row, col] is equal to info_mat[(col - 1)* 12 (number of rows) row] but info_mat[i] and info_mat[i 1] can be in different columns.

And if you want to create data.frame with you data use this code:

df = data.frame(
    data = c("2000-01-01", "2000-01-02", "2000-01-03", "2000-01-04", "2000-01-05", "2000-01-06", "2000-01-07", "2000-01-08", "2000-01-09", "2000-01-10", "2000-01-11", "2000-01-12"),
    a1 = c(0, 0, 0, 0, 6421, 41, 5667, 44, 1178, 0, 1070, 1),
    b1 = c(1, 1, 1, 1, 6421, 41, 5667, 44, 1178, 0, 1070, 1)
)
  • Related