在R中使用apply系列函数计算多基数下的每日生长度日
多基数生长度日(GDD)无循环计算方案
首先明确生长度日的通用计算逻辑:每日平均温度减去基数,结果取与0的较大值,公式为:GDD = max(0, (tmax + tmin)/2 - base)
步骤1:定义计算函数与模拟数据
# 定义GDD计算函数 gdd_func <- function(tmin, tmax, base) { avg_temp <- (tmin + tmax) / 2 pmax(0, avg_temp - base) } # 生成模拟数据(设种子保证结果可复现) set.seed(123) tmin <- runif(10, 30, 60) # 10个最低温数据 tmax <- runif(10, 70, 90) # 10个最高温数据 bases <- c(40, 45, 50) # 多个计算基数
步骤2:用apply系列函数实现无循环计算
方法1:sapply(简洁直观)
sapply可以遍历bases中的每个基数,对完整的tmin和tmax向量计算GDD,返回10行3列的矩阵(每行对应1天,每列对应一个基数):
gdd_results <- sapply(bases, function(b) gdd_func(tmin, tmax, b)) colnames(gdd_results) <- paste0("base_", bases)
方法2:vapply(类型安全)
如果需要严格指定输出类型,用vapply更稳妥,提前声明输出为长度10的数值向量:
gdd_results <- vapply(bases, function(b) gdd_func(tmin, tmax, b), numeric(10)) colnames(gdd_results) <- paste0("base_", bases)
修正mapply的用法(解决你之前的问题)
你之前用mapply不符合预期,是因为默认会把tmin、tmax、bases按元素配对循环。要让每个基数对应完整的温湿度数据,需用MoreArgs参数传递tmin和tmax:
gdd_results <- mapply(gdd_func, base = bases, MoreArgs = list(tmin = tmin, tmax = tmax)) colnames(gdd_results) <- paste0("base_", bases)
结果示例
运行上述代码后,gdd_results的结构为:
base_40 base_45 base_50 [1,] 24.67702 19.67702 14.67702 [2,] 24.80437 19.80437 14.80437 [3,] 22.50584 17.50584 12.50584 [4,] 25.97677 20.97677 15.97677 [5,] 23.47527 18.47527 13.47527 [6,] 23.87740 18.87740 13.87740 [7,] 21.52117 16.52117 11.52117 [8,] 24.34566 19.34566 14.34566 [9,] 22.27274 17.27274 12.27274 [10,] 25.15914 20.15914 15.15914
内容的提问来源于stack exchange,提问作者user8229029
相关产品推荐
相关产品推荐

