如何在R语言中为每个受试者重复执行分析代码并将结果追加至centralities数据框?
Alright, let's figure out how to run this repeated analysis for every subject efficiently in R. I'll walk you through two reliable methods—one using base R, and another with the tidyverse for a more streamlined workflow.
Base R Loop (Straightforward & Compatible)
First, we'll avoid the inefficient row-by-row appending you were using (it forces R to reallocate memory every time, which slows things down with large datasets). Instead, we'll store results in a list first, then combine them at the end.
Grab all unique subject IDs from your dataset:
unique_subjects <- unique(fullDataDetrend$subjno)Initialize an empty list to hold results for each subject:
centrality_results <- list()Loop through each subject, run your analysis, and store the output:
for (subj in unique_subjects) { # Subset data for the current subject fullDataDetrend_subj <- subset(fullDataDetrend, subjno == subj, select = c(subjno, depressed, sad, tired, interest, happy, neg_thoughts, concentration_probl, ruminating, activity, datevar, timestamp, dayno, beepno)) # Fit the VAR model model_subj <- var1(fullDataDetrend_subj) # Extract the omega_zeta matrix model_subj_omega <- getmatrix(model_subj, "omega_zeta") # Calculate centrality metrics centrality_model_subj_omega <- centrality(model_subj_omega) # Store results in the list (as a data frame for easy combining later) centrality_results[[as.character(subj)]] <- data.frame( subject_id = subj, InExpectedInfluence = centrality_model_subj_omega$InExpectedInfluence ) }Combine all list entries into your final
centralitiesdata frame:centralities <- do.call(rbind, centrality_results)
Tidyverse + purrr (Cleaner Pipeline)
If you prefer a more readable, pipeline-style approach, the tidyverse's dplyr and purrr packages make this a breeze.
Load the required packages first:
library(dplyr) library(purrr)Use nesting and map functions to run the analysis per subject:
centralities <- fullDataDetrend %>% # Keep only the columns you need select(subjno, depressed, sad, tired, interest, happy, neg_thoughts, concentration_probl, ruminating, activity, datevar, timestamp, dayno, beepno) %>% # Group data by subject group_by(subjno) %>% # Nest each subject's data into a list column nest() %>% # Run each step of your analysis on the nested data mutate( model = map(data, ~var1(.x)), omega_matrix = map(model, ~getmatrix(.x, "omega_zeta")), centrality = map(omega_matrix, ~centrality(.x)), # Extract the specific metric you need InExpectedInfluence = map_dbl(centrality, ~.x$InExpectedInfluence) ) %>% # Keep only the columns you care about select(subjno, InExpectedInfluence) %>% rename(subject_id = subjno) %>% ungroup()
Pro Tips for Robustness
- Handle errors gracefully: Some subjects might have insufficient data for the
var1model. Add error handling to skip problematic cases and log issues:- In base R, use
tryCatch()inside the loop:for (subj in unique_subjects) { tryCatch({ # Your analysis code here centrality_results[[as.character(subj)]] <- data.frame(...) }, error = function(e) { message(paste("Skipping subject", subj, "due to error:", e$message)) }) } - In tidyverse, use
safely()to wrap your analysis function and capture errors:safe_centrality <- safely(function(data) { model <- var1(data) omega <- getmatrix(model, "omega_zeta") centrality(omega)$InExpectedInfluence }) centralities <- fullDataDetrend %>% select(...) %>% group_by(subjno) %>% nest() %>% mutate( result = map(data, safe_centrality), InExpectedInfluence = map_dbl(result, "result"), error_message = map_chr(result, ~ifelse(is.null(.x$error), NA_character_, .x$error$message)) ) %>% select(subjno, InExpectedInfluence, error_message) %>% ungroup()
- In base R, use
内容的提问来源于stack exchange,提问作者Brage Kraft

