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:
- you have no variable
i
and don't use variablesrow
andcol
. - what is the type of
evolution
variable? info_mat[i 1]
is not numeric. You cannot divide it oninfo_mat[i]
.- What does
info_mat[i]
means? Yes,info_mat[row, col]
is equal toinfo_mat[(col - 1)* 12 (number of rows) row]
butinfo_mat[i]
andinfo_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)
)