如何在R语言中遍历命名列表并提取数据进行计算?
问题:遍历含DataFrame的列表并计算统计量
我通过模拟不同参数值的模型,得到了一个包含多个DataFrame的列表对象results,模拟代码如下:
library(MASS) model_beta <- 0 model_se <- 0 model_p <- 0 set.seed(seed = 42224) sim <- function(S, T, rho1, rho2, sigma_u, sigma_v) { Sigma <- matrix(c(sigma_u, 0, 0, sigma_v), 2, 2) uv <- data.frame(mvrnorm(n = S * T, mu = c(0, 0), Sigma = Sigma)) for (s in 1:S){ x_t <- 0 + uv[(s - 1) * T + 1, 2] y_t <- 0 + uv[(s - 1) * T + 1, 1] for(i in 2:T) { x_t[i] <- rho2 * x_t[i - 1] + uv[(s - 1) * T + i, 2] y_t[i] <- rho1 * y_t[i - 1] + uv[(s - 1) * T + i, 1] } data <- data.frame(y_t, x_t) model <- lm(y_t ~ 1 + x_t, data) model_beta[s] <- model$coefficients[2] model_se[s] <- summary(model)$coefficients[2, 2] model_p[s] <- summary(model)$coefficients[, "Pr(>|t|)"][2] rm(x_t, y_t, data) all_ests <- as.data.frame(cbind(model_beta, model_se, model_p)) } return(all_ests) } rho1_values <- c(0.1, 0.95, 0.99) rho2_values <- c(0.1, 0.95, 0.99) T_values <- c (100, 500, 1000) results <- list() for (rho1 in rho1_values) { for (rho2 in rho2_values) { for (T in T_values) { result <- sim(S = 100, T, rho1, rho2, sigma_u = 1, sigma_v = 1) results[[paste("rho1", rho1, "rho2", rho2, "T", T)]] <- result } } }
我想遍历results中的每个DataFrame,计算model_beta的均值、标准差,以及model_p小于等于0.05的数量,但尝试用results$key$model_beta的方式无法生效,我的尝试代码如下:
# recover beta mean and se estimates mean_betas <- list() sd_betas <- list() p_betas <- list() for (key in names(results)) { beta <- mean(results$key$model_beta) sd <- sd(results$key$model_beta) ttest <- sum(results$key$model_p <= 0.05) mean_betas[[key]] <- beta sd_betas[[key]] <- sd p_betas[[key]] <- ttest }
解决方法
错误原因
results$key写法无效,因为$运算符只能识别字面量形式的名称,而key是循环中的变量,需要用[[ ]]索引来访问变量对应的列表元素。
方法1:基础循环修正
修改循环内的元素访问方式,用[[key]]获取当前DataFrame,同时避免使用内置函数名(如sd)作为变量名:
mean_betas <- list() sd_betas <- list() p_betas <- list() for (key in names(results)) { # 获取当前参数组合对应的DataFrame current_df <- results[[key]] # 计算所需统计量 beta_mean <- mean(current_df$model_beta) beta_sd <- sd(current_df$model_beta) sig_p_count <- sum(current_df$model_p <= 0.05) # 存入结果列表 mean_betas[[key]] <- beta_mean sd_betas[[key]] <- beta_sd p_betas[[key]] <- sig_p_count }
方法2:用purrr包简化遍历
如果习惯使用tidyverse工具,purrr包的imap函数可以更简洁地完成带键名的遍历,一次性生成所有统计量:
library(purrr) # 遍历列表,同时获取DataFrame和对应的键名 summary_stats <- imap(results, function(df, key) { list( mean_beta = mean(df$model_beta), sd_beta = sd(df$model_beta), sig_p_count = sum(df$model_p <= 0.05) ) }) # 拆分到单独的结果向量(可选) mean_betas <- map_dbl(summary_stats, "mean_beta") sd_betas <- map_dbl(summary_stats, "sd_beta") p_betas <- map_int(summary_stats, "sig_p_count")
内容的提问来源于stack exchange,提问作者aerw4
相关产品推荐
相关产品推荐

