Другой вариант:
i <- DT1[Month > 12L, which=TRUE]
DT1[i, Month := Month - 12L][-i, Year := Year - 1L]
Обратите внимание, что на сайте rdatatable github находится в стадии разработки fifelse
.
Временная привязка с использованием фактической яркости:
# A tibble: 4 x 14
expression min mean median max `itr/sec` mem_alloc n_gc n_itr total_time result memory time gc
<chr> <bch:tm> <bch:tm> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl> <int> <bch:tm> <list> <list> <list> <list>
1 for_loop 1.92s 1.92s 1.92s 1.92s 0.521 4.66GB 110 1 1.92s <NULL> <Rprofmem [25,175 x 3~ <bch:t~ <tibble [1 x 3]>
2 mtd0 1.45ms 2.26ms 1.7ms 7.49ms 442. 6.55MB 31 221 500.02ms <data.table [25,000 x ~ <Rprofmem [67 x 3]> <bch:t~ <tibble [221 x ~
3 mtd1 498.46us 650.79us 566.1us 2.98ms 1537. 699.56KB 6 768 499.81ms <data.table [25,000 x ~ <Rprofmem [24 x 3]> <bch:t~ <tibble [768 x ~
4 basemtd 950.97us 1.41ms 1.02ms 50.65ms 709. 5.06MB 41 355 500.45ms <dbl [25,000]> <Rprofmem [52 x 3]> <bch:t~ <tibble [355 x ~
Base R уже очень быстр для 25 000 строк данных.
data:
set.seed(0L)
DT <- data.table(FinancialPeriod=sample(12L, 25e3L, TRUE),
FinancialYear=c(2018))
DT[, c("Month","Year") := .(FinancialPeriod + 6L, FinancialYear)]
DT0 <- copy(DT)
DT1 <- copy(DT)
DF <- setDF(copy(DT))
временной код:
bench::mark(
for_loop = {
for(row in 1:nrow(DF)){
if (DF[row,"Month"] > 12){
DF[row,"Month"]<- DF[row,"Month"] -12
}
else {
DF[row,"Year"]<- DF[row,"Year"] -1
}
}
},
mtd0=DT0[, c("Month", "Year") := list(ifelse(Month > 12, Month-12, Month),
ifelse(Month <= 12, Year-1, Year))],
mtd1={
i <- DT1[Month > 12L, which=TRUE]
DT1[i, Month := Month - 12L][-i, Year := Year - 1L]
},
basemtd={
DF0$Month <- ifelse(DF0$Month > 12L, DF0$Month - 12L, DF0$Month)
DF0$Year <- ifelse(DF0$Month <= 12L, DF0$Year - 1L, DF0$Year)
},
check=FALSE
)