Пример данных
set.seed(123)
df <- data.frame(day = 1:365, Precp = sample(1:30, 365, replace = T),
ETo = sample(1:10, 365, replace = T), top.FC = 23, CN = 61, DC = 0.4)
Эти данные имеют день года, количество осадков и суммарное испарение, а также некоторые константы, такие как top.FC, CN и DC.Для данного дня i функция water.update
рассчитывает почвенную воду для дня i
water.update <- function(WAT0, RAIN.i, ETo.i, CN, DC, top.FC){
S = 25400/CN - 254; IA = 0.2*S
if (RAIN.i > IA) { RO = (RAIN.i - 0.2 * S)^2/(RAIN.i + 0.8 * S)
} else {
RO = 0
}
if (WAT0 + RAIN.i - RO > top.FC) {
DR = DC * (WAT0 + RAIN.i - RO - top.FC)
} else {
DR = 0
}
dWAT = RAIN.i - RO - DR - ETo.i
WAT1 = WAT0 + dWAT
WAT1 <- ifelse(WAT1 < 0, 0, WAT1)
return(list(WAT1,RO,DR))
}
Функция water.model
применяет water.update
для всех дней.Он рекурсивный, т.е. каждый день почвенная вода нуждается в почвенной воде предыдущего дня.Следовательно, цикл в функции water.model
.
water.model <- function(dat){
top.FC <- unique(dat$top.FC)
# I make a vector to store the results
dat$WAT <- -9999.9
dat$RO <- -9999.9
dat$DR <- -9999.9
# First day (day 1) has a default value
dat$WAT[1] <- top.FC/2 # assuming top soil water is half the content on day 1
dat$RO[1] <- NA
dat$DR[1] <- NA
# Now calculate water content for day 2 onwards
for(d in 1:(nrow(dat)-1)){
dat[d + 1,7:9] <- water.update(WAT0 = dat$WAT[d],
RAIN.i = dat$Precp[d + 1],
ETo.i = dat$ETo[d + 1],
CN = unique(dat$CN),
DC = unique(dat$DC),
top.FC = unique(dat$top.FC))
}
return(dat)
}
ptm <- proc.time()
result <- water.model(df)
proc.time() - ptm
user system elapsed
0.18 0.00 0.17
Цикл for в этом случае неизбежен, поскольку он использует содержание воды предыдущего дня для определения содержания воды текущего дня.
Есть ли более быстрый способ написать вышеуказанную функцию?Я ищу для ускорения этого кода.Причина в том, что мои реальные данные намного больше.