【问题标题】:R looping matrix elementsR循环矩阵元素
【发布时间】:2024-09-04 19:20:01
【问题描述】:

我正在尝试遍历矩阵列。

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)

我想计算每个变量月份之间的进化率 (V+1 - V)/V (进化从一月到二月,二月到三月,...,对于a1,...,hb4) 并在我将命名为“evolution_matrix”的矩阵中得到结果

我尝试了以下方法,但由于某种原因它不起作用。 请注意,我在这里表示我想为每个变量执行进化的事实。我认为 i 是: 进化(变量 a1 的 1 月到 2 月)= (a1 2 月份的值 - a1 1 月份的值)/(a1 1 月份的值)。

我不知道如何对其建模,因此我输入了 i,但它没有引用矩阵中的任何内容。

  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]])
    }
  }

请帮忙!

【问题讨论】:

  • 循环中的i 是什么?
  • 示例数据是一个字符矩阵,我们无法对其进行数学运算,请更新您的示例。 forloops里面有一个i它是从哪里来的?
  • 请看我的编辑。

标签: r loops matrix tidyverse


【解决方案1】:

为什么要使用矩阵?您在矩阵中只有字符(字符串)变量,但您想将它们用作数字。我认为 data.frame 是个好主意。
R 包dplyr 具有函数 lapply 可以将您的函数应用于每一列并通过列表简化结果。但是我们不想对列日期应用“进化”函数。

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

在最后一行中,我将列表转换为 data.frame(为了美观的打印)。
但是我们忘记了“日期”列。让我们将它添加到我们的 data.frame 中。

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

就是这样。但是如果你想通过循环来做,你可以使用这个代码:

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
    }
}

对您的代码示例的评论:

  1. 您没有变量i,也不要使用变量rowcol
  2. evolution 变量的类型是什么?
  3. info_mat[i+1] 不是数字。你不能在info_mat[i]上划分它。
  4. info_mat[i] 是什么意思?是的,info_mat[row, col] 等于 info_mat[(col - 1)* 12 (number of rows) + row],但 info_mat[i]info_mat[i + 1] 可以位于不同的列中。

如果您想用您的数据创建 data.frame,请使用以下代码:

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)
)

【讨论】: