Заполнить данные кадр за столбцом с помощью цикла for

Я создал пустой фрейм данных с 11 столбцами и 15 строками и впоследствии назвал столбцы.

L_df <- data.frame(matrix(ncol = 11, nrow = 15))
names(L_df) <- paste0("L_por", 0:10)

w <- c(0.2, 0.4, 0.6, 0.8, 1, 1.2, 1.4, 1.6, 1.8, 2, 2.2, 2.4, 2.6,  2.8, 3)
wu <- 0
L <- 333.7
pm <- c(2600, 2574, 2548, 2522, 2496, 2470, 2444, 2418, 2392, 2366,  2340)

Фрейм данных выглядит следующим образом:

head(L_df)
  L_por0 L_por1 L_por2 L_por3 L_por4 L_por5 L_por6 L_por7 L_por8 L_por9 L_por10
1     NA     NA     NA     NA     NA     NA     NA     NA     NA     NA      NA
2     NA     NA     NA     NA     NA     NA     NA     NA     NA     NA      NA
3     NA     NA     NA     NA     NA     NA     NA     NA     NA     NA      NA
4     NA     NA     NA     NA     NA     NA     NA     NA     NA     NA      NA
5     NA     NA     NA     NA     NA     NA     NA     NA     NA     NA      NA
6     NA     NA     NA     NA     NA     NA     NA     NA     NA     NA      NA

Теперь я хотел бы заполнить данные кадр за столбцом на основе формулы. Я попытался выразить это с помощью вложенного цикла:

 for (i in 1:ncol(L_df)) {
  pm_tmp <- pm[i]
  col_tmp <- colnames(L_df)[i]
  for (j in 1:nrow(L_df)) {
    w_tmp <- w[j]
    L_por_tmp <- pm_tmp*L*((w_tmp-wu)/100)
    col_tmp[j] <- L_por_tmp
  }
}

Для каждого столбца я перебираю предопределенный вектор pm длины 11. Для каждой строки я перебираю предопределенный вектор w длиной 15 (повторяется каждый столбец).

Пример: сначала выберите pm[1] для первого столбца. Во-вторых, выберите w[i] для каждой строки в первом столбце. Сохраните формулу в L_por_tmp и использовать его, чтобы заполнить первый столбец от row1 до row15. Вся процедура должна начаться заново для второго столбца (с pm[2]) с w[i] для каждого ряда и тд. wu а также L фиксируются в формуле.

R выполняет код без ошибок. Когда я проверяю значения tmp, они верны. Тем не менее, фрейм данных остается пустым. L_df не заполняется. Я хотел бы решить эту проблему с помощью цикла, но если у вас есть другие решения, я рад их услышать! У меня сложилось впечатление, что может быть более плавный способ сделать это. Ура!

2 ответа

Решение

Решение

L_df <- data.frame(sapply(pm, function(x) x * L * ((w - wu) / 100)))
names(L_df) <- c("L_por0", "L_por1", "L_por2", "L_por3", "L_por4", "L_por5",
                 "L_por6", "L_por7", "L_por8", "L_por9", "L_por10")
L_df
 L_por0    L_por1    L_por2    L_por3    L_por4    L_por5    L_por6    L_por7
1   1735.24  1717.888  1700.535  1683.183  1665.830  1648.478  1631.126  1613.773
2   3470.48  3435.775  3401.070  3366.366  3331.661  3296.956  3262.251  3227.546
3   5205.72  5153.663  5101.606  5049.548  4997.491  4945.434  4893.377  4841.320
4   6940.96  6871.550  6802.141  6732.731  6663.322  6593.912  6524.502  6455.093
5   8676.20  8589.438  8502.676  8415.914  8329.152  8242.390  8155.628  8068.866
6  10411.44 10307.326 10203.211 10099.097  9994.982  9890.868  9786.754  9682.639
7  12146.68 12025.213 11903.746 11782.280 11660.813 11539.346 11417.879 11296.412
8  13881.92 13743.101 13604.282 13465.462 13326.643 13187.824 13049.005 12910.186
9  15617.16 15460.988 15304.817 15148.645 14992.474 14836.302 14680.130 14523.959
10 17352.40 17178.876 17005.352 16831.828 16658.304 16484.780 16311.256 16137.732
11 19087.64 18896.764 18705.887 18515.011 18324.134 18133.258 17942.382 17751.505
12 20822.88 20614.651 20406.422 20198.194 19989.965 19781.736 19573.507 19365.278
13 22558.12 22332.539 22106.958 21881.376 21655.795 21430.214 21204.633 20979.052
14 24293.36 24050.426 23807.493 23564.559 23321.626 23078.692 22835.758 22592.825
15 26028.60 25768.314 25508.028 25247.742 24987.456 24727.170 24466.884 24206.598
      L_por8    L_por9   L_por10
1   1596.421  1579.068  1561.716
2   3192.842  3158.137  3123.432
3   4789.262  4737.205  4685.148
4   6385.683  6316.274  6246.864
5   7982.104  7895.342  7808.580
6   9578.525  9474.410  9370.296
7  11174.946 11053.479 10932.012
8  12771.366 12632.547 12493.728
9  14367.787 14211.616 14055.444
10 15964.208 15790.684 15617.160
11 17560.629 17369.752 17178.876
12 19157.050 18948.821 18740.592
13 20753.470 20527.889 20302.308
14 22349.891 22106.958 21864.024
15 23946.312 23686.026 23425.740

объяснение

sapply() Функция может быть использована для итерации по векторам более идиоматическим способом для R-программирования. Перебираем pm и используйте вашу формулу один раз, так как R векторизована; каждый раз он создает вектор длиной 15 (то есть 11 векторов длиной 15), и когда мы обертываем его в data.frame() возвращает фрейм данных, который вы хотите, и мы добавляем в имена столбцов.

ПРИМЕЧАНИЕ. Применение функций к каждому элементу вектора с использованием apply() Семейная функция имеет несколько иное значение, чем использование итераций для циклов. В твоем случае я думаю sapply() это проще и понятнее. Для получения дополнительной информации о том, когда вам нужен цикл или когда что-то вроде применения лучше, см., Например, это обсуждение из книги Advanced R. Хэдли Уикхэма.

Вы просто делаете небольшую ошибку, и вы были почти там, отредактировав свою функцию:

for (i in 1:ncol(L_df)) {
  pm_tmp <- pm[i]
  col_tmp <- colnames(L_df)[i]
  for (j in 1:nrow(L_df)) {
    w_tmp <- w[j]
    L_por_tmp <- pm_tmp*L*((w_tmp-wu)/100)
    L_df[ j ,col_tmp] <- L_por_tmp ##You must have used df[i, j] referencing here
  }
}

Выход:

Просто печатаем голову в несколько рядов:

L_df
     L_por0    L_por1    L_por2    L_por3    L_por4    L_por5    L_por6    L_por7    L_por8    L_por9   L_por10
1   1735.24  1717.888  1700.535  1683.183  1665.830  1648.478  1631.126  1613.773  1596.421  1579.068  1561.716
2   3470.48  3435.775  3401.070  3366.366  3331.661  3296.956  3262.251  3227.546  3192.842  3158.137  3123.432
3   5205.72  5153.663  5101.606  5049.548  4997.491  4945.434  4893.377  4841.320  4789.262  4737.205  4685.148
Другие вопросы по тегам