R语言利用三个矩阵对应值调用uniroot求解方程根的实现问题
求解方案
核心思路
你需要对每一行的a、b参数,分别对应三个年份的pop、event取值单独求解方程,原写法直接传入整个矩阵会导致uniroot无法识别单一求解目标,所以我们通过逐行逐列遍历调用uniroot实现需求,同时也可以直接用解析解计算(效率更高)。
完整可运行代码
# 构造三个矩阵(兼容base R写法,无需额外依赖) df <- data.frame( a = c(-5.8221, -6.4678, -6.1213, -5.4518, -5.3527, -5.3517, -5.3169), b = c(.0234, .0199, .0162, .0151, .0148, .0138, .0123) ) a_b <- as.matrix(df[1:7, 1:2]) df1 <- data.frame( "2000" = c(716209.27, 642504.69, 644640.11, 632239.35, 552437.34, 554395.34, 539358.87), "2005" = c(653040.76, 637752.95, 651635.40, 647572.55, 641183.99, 570938.83, 554092.75), "2010" = c(5643.6, 876123, 665412.5, 98643, 89012, 776321, 8863), check.names = FALSE ) pop <- as.matrix(df1[1:7, 1:3]) df2 <- data.frame( "2000" = c(9968.50418, 2605.16992, 2937.01261, 4286.23376, 5718.80904, 4843.19769, 5077.52440), "2005" = c(6037.16994, 2336.72681, 2391.55031, 4085.62207, 5000.77218, 4425.02331, 5097.25052), "2010" = c(19123.45, 87765.54, 102345.44, 98000, 12396, 90076, 10133), check.names = FALSE ) event <- as.matrix(df2[1:7, 1:3]) # 初始化结果矩阵,和pop同维度、同列名 result <- matrix(NA, nrow = nrow(pop), ncol = ncol(pop), dimnames = dimnames(pop)) # 逐行逐列调用uniroot求解 for (i in seq_len(nrow(a_b))) { a <- a_b[i, 1] b <- a_b[i, 2] for (j in seq_len(ncol(pop))) { e_val <- event[i, j] p_val <- pop[i, j] # 定义单目标求解函数 f <- function(x) { e_val - exp(a + b * x) * p_val } # 调用uniroot求解,存根到结果矩阵 result[i, j] <- uniroot(f, c(-10000, 10000), extendInt = "yes")$root } } # 保留4位小数输出,和你预期格式一致 round(result, 4) # (可选)解析解直接计算,效率更高,结果完全一致 # result_analytical <- (log(event/pop) - a_b[,1])/a_b[,2] # round(result_analytical, 4)
输出结果
运行代码后会得到你需要的格式:
2000 2005 2010 [1,] 66.1349 48.6493 300.9612 [2,] 48.2373 43.1457 209.3950 [3,] 45.0617 31.7133 262.2990 [4,] 30.3271 25.5657 360.6132 [5,] 52.8459 33.7145 228.4664 [6,] 44.3041 35.6299 231.7237 [7,] 52.9546 51.0787 443.1554
内容的提问来源于stack exchange,提问作者mehmo
相关产品推荐
相关产品推荐

