我正试图在R中找出一个简单的土壤水平衡。这是我需要做的步骤:
对于某一年,从200日起,我需要确定土壤水分(SWi),其计算方法如下:
`SW(i) = SW(i-1) + Rain(i) - ETo(i)`
其中SW(i-1)
是前一天的含水量,Rain(i)
是降雨量,ETo(i)
是第i天的蒸散量
条件是SW(i)不能为负或大于SW(max)为20。
以下是一个示例数据:
library(tidyverse)
set.seed(123)
dat <- tibble(
year = rep(1980:2015, each = 100),
day = rep(200:299, times = 36),
rain = sample(0:17, size = 100*36,replace = T),
eto = sample(2:9, size = 100*36,replace = T))
SW.initial <- data.frame(year= 1980:2015, SW.199 = sample(1:10, 36, replace = T))
SW.initial是每年的doy 199含水量
SW.max <- 20
dat$SW.fin <- NA
以1980年为例
dat.1980 <- dat[dat$year == 1980,]
SW.initial.1980 <- SW.initial[SW.initial$year== 1980,"SW.199"]
for(doy in dat.1980$day){
SW <- SW.initial.1980
SW <- SW + dat.1980[dat.1980$day == doy, "rain"] - dat.1980[dat.1980$day == doy, "eto"]
SW <- ifelse(SW < 0, 0, ifelse(SW >= SW.max, SW.max, SW))
dat[dat$year == years & dat$day == doy,"SW.fin"] <- SW
SW.initial.1980 <- SW
}
这个循环会给我每天开始使用以下内容的SW:200到299:
`SW(i) = SW(i-1) + Rain[i] + ETo[i]``
对于doy 200,SW(i-1)来自SW.initial
数据框
我可以遍历所有年份:
for(years in unique(dat$year)){
test <- dat[dat$year == years,]
SW.in <- SW.initial[SW.initial$year == years,"SW.199"]
for(doy in test$day){
SW <- SW.in
SW <- SW + test[test$day == doy, "rain"] - test[test$day == doy, "eto"]
SW <- ifelse(SW < 0, 0, ifelse(SW >= SW.max, SW.max, SW))
dat[dat$year == years & dat$day == doy,"SW.fin"] <- SW
SW.in <- SW
}}
我真的想避免这个长循环,并且正在考虑是否有更聪明(更快的方法)。
答案 0 :(得分:0)
这会给你想要的吗?
修改 - &gt;按年份分组添加
dat %>% group_by(year) %>% mutate(sw_oneless = c(NA, day[1:length(day)-1]),
sw_oneless + rain - eto)
# A tibble: 3,600 x 6
# Groups: year [36]
year day rain eto sw_oneless `sw_oneless + rain - eto`
<int> <int> <int> <int> <int> <int>
1 1980 200 5 2 NA NA
2 1980 201 14 6 200 208
3 1980 202 7 4 201 204
4 1980 203 15 5 202 212
5 1980 204 16 5 203 214
6 1980 205 0 8 204 196
7 1980 206 9 9 205 205
8 1980 207 16 6 206 216
9 1980 208 9 9 207 207
10 1980 209 8 4 208 212
# ... with 3,590 more rows
解决&#34;问题&#34;在第200天,为什么不从原始数据中过滤掉第199-300天?然后,您可以运行我的代码和na.omit()或再次过滤,第199天的行已经消失。 或者,如果您不能这样做,请将SW.initial与您的数据数据框合并