Katakanlah saya memiliki kumpulan data berikut dt dan konstanta constant.

dt <- structure(list(var1 = c(-92186.7470607738, -19163.5035325072, 
                              -18178.8396858014, -9844.67882723287, -16494.7802822178, -17088.0576319257
), var2 = c(-3.12, NA, NA, NA, NA, NA)), class = c("data.table", 
                                                   "data.frame"), row.names = c(NA, -6L))

constant <- 608383

print(dt)
         var1  var2
1: -92186.747 -3.12
2: -19163.504    NA
3: -18178.840    NA
4:  -9844.679    NA
5: -16494.780    NA
6: -17088.058    NA

Nilai var2 tergantung pada nilai baris sebelumnya, seperti ini

for(i in 2:nrow(dt)){
  prev <- dt[(i-1),]
  dt[i, var2 := prev$var2 - var1/constant]
}

print(dt)
         var1      var2
1: -92186.747 -3.120000
2: -19163.504 -3.088501
3: -18178.840 -3.058620
4:  -9844.679 -3.042439
5: -16494.780 -3.015326
6: -17088.058 -2.987238

Meskipun for loop ini memberikan output yang diinginkan, ini sangat lambat pada kumpulan data yang besar. Apakah ada cara yang lebih cepat untuk mencapai hasil ini? Sebaiknya menggunakan data.table.

r
4
maarvd 26 Mei 2021, 17:28

2 jawaban

Jawaban Terbaik

Berikut adalah solusi menggunakan fungsi accumulate dari paket purrr jika Anda tertarik. Dalam solusi ini .y mewakili nilai var1 saat ini yang ingin kita ulangi dan .x mewakili nilai akumulasi yang kita hitung dan masukkan ke dalam kolom var2. Seperti yang mungkin Anda perhatikan, saya mengecualikan nilai pertama var1 karena kami tidak menerapkan rumus kami di dalamnya.

library(dplyr)
library(purrr)

dt %>%
  mutate(var2 = accumulate(var1[-1], .init = var2[1], ~ .x - .y /constant))


         var1      var2
1: -92186.747 -3.120000
2: -19163.504 -3.088501
3: -18178.840 -3.058620
4:  -9844.679 -3.042439
5: -16494.780 -3.015326
6: -17088.058 -2.987238
2
Anoushiravan R 26 Mei 2021, 22:26

Varian BaseR dari jawaban di atas diusulkan oleh teman baik (yang dapat Anda gunakan dengan mudah di sintaks data.table Anda)

dt <- structure(list(var1 = c(-92186.7470607738, -19163.5035325072, 
                              -18178.8396858014, -9844.67882723287, -16494.7802822178, -17088.0576319257
), var2 = c(-3.12, NA, NA, NA, NA, NA)), class = c("data.table", 
                                                   "data.frame"), row.names = c(NA, -6L))

dt
#>         var1  var2
#> 1 -92186.747 -3.12
#> 2 -19163.504    NA
#> 3 -18178.840    NA
#> 4  -9844.679    NA
#> 5 -16494.780    NA
#> 6 -17088.058    NA
constant <- 608383
Reduce(function(.x, .y) .x - .y /constant , dt$var1[-1], init = dt$var2[1], accumulate = T)
#> [1] -3.120000 -3.088501 -3.058620 -3.042439 -3.015326 -2.987238

Dibuat pada 26-05-2020 oleh paket reprex (v2.0.0)

2
AnilGoyal 26 Mei 2021, 15:44