如何为group_map生成的gt列表命名并在循环中匹配关联数据?
问题
我封装了一个基于group_map的函数,用于为数据集的每个分组生成GT表格,运行后得到gt_list,但该列表的元素没有命名,只能通过gt_list[[i]]的位置索引调用。我希望构建一个for循环,将另一个数据集data2中的州降水量数据与gt_list中对应州的GT表格匹配输出,但state_list存储的是state_id的数值,直接用其作为gt_list的下标会触发错误:Error in gt_list[[i]] : subscript out of bounds。请问如何实现对应调用?是否需要修改原group_map函数?
现有代码
library(tidyverse) library(gt) group_var <- "State" select_vect <- c("City", "Elevation", "NumObserved") create_gts_and_map <- function(df, group_var, title_text) { df %>% group_by(.data[[group_var]]) %>% group_map( function(.x, .y, select_vect) { df_ind_clean <- .x %>% select(all_of(select_vect)) gt <- gt(df_ind_clean) %>% tab_header(title = paste(title_text, .y)) return(gt) }, select_vect = select_vect) } gt_list <- create_gts_and_map(df = ex_data, group_var = group_var, title_text = "State Chart:") state_list_temp <- ex_data %>% pull(state_id) state_list <- unique(state_list_temp)
尝试的循环代码
for (i in state_list) { print(data2$Precipitation[i]) print(gt_list[[i]]) }
数据集
ex_data <- structure(list(state_id = c(22L, 22L, 22L, 11L, 11L, 11L, 33L, 33L, 33L), State = c("California", "California", "California", "Texas", "Texas", "Texas", "New Mexico", "New Mexico", "New Mexico" ), City = c("Los Angeles", "San Francisco", "Fresno", "Dallas", "Austin", "Frisco", "Albuquerque", "Santa Fe", "Taos"), NumObserved = c(1200000L, 825000L, 113000L, 240000L, 189000L, 38000L, 56000L, 23000L, 6000L ), Elevation = c(28L, 47L, 235L, 312L, 550L, 128L, 4291L, 3533L, 7823L)), class = "data.frame", row.names = c(NA, -9L)) data2 <- structure(list(state_id = c(22L, 33L, 42L, 32L, 12L, 14L, 23L, 11L), State = c("California", "New Mexico", "New York", "Minnesota", "Georgia", "Florida", "South Carolina", "Texas"), Precipitation = c(32L, 8L, 49L, 45L, 38L, 61L, 52L, 24L)), class = "data.frame", row.names = c(NA, -8L))
解决方案
错误原因
gt_list的长度是3(对应ex_data里的3个州分组),列表的下标只能是位置索引(1、2、3)或命名索引(如州名/state_id)。而state_list里的数值是22、11、33,这些数值远大于列表长度,自然会触发下标越界错误。
方案1:修改原函数,给gt_list元素命名(推荐)
直接在group_map后添加set_names,用分组的state_id或州名作为列表元素的名称,这样就能直接通过state_id或州名索引对应的GT表格。
修改后的函数代码
create_gts_and_map <- function(df, group_var, title_text) { df %>% group_by(.data[[group_var]]) %>% # 先分组生成GT表格,再给列表元素命名为对应的state_id group_map( function(.x, .y, select_vect) { df_ind_clean <- .x %>% select(all_of(select_vect)) gt(df_ind_clean) %>% tab_header(title = paste(title_text, .y)) }, select_vect = select_vect) %>% # 提取每个分组的state_id作为列表名称 set_names(df %>% distinct(.data[[group_var]], state_id) %>% arrange(.data[[group_var]]) %>% pull(state_id)) } # 重新生成带命名的gt_list gt_list <- create_gts_and_map(df = ex_data, group_var = group_var, title_text = "State Chart:")
匹配循环代码
现在可以直接用state_id作为索引,同时从data2中匹配对应降水量:
for (sid in state_list) { # 从data2中筛选对应state_id的降水量 precip <- data2$Precipitation[data2$state_id == sid] cat(paste("State ID", sid, "降水量:", precip, "\n")) # 通过state_id索引对应的GT表格(需转成字符型) print(gt_list[[as.character(sid)]]) }
方案2:不修改原函数,通过州名匹配调用
如果不想修改原函数,可以先获取ex_data中分组的州名列表,再通过州名匹配找到gt_list的位置索引。
实现代码
# 获取ex_data中分组的州名(顺序和gt_list完全一致) state_names_ordered <- unique(ex_data$State) for (sid in state_list) { # 找到当前state_id对应的州名 current_state <- ex_data$State[ex_data$state_id == sid][1] # 找到该州名在state_names_ordered中的位置 list_index <- which(state_names_ordered == current_state) # 提取对应降水量 precip <- data2$Precipitation[data2$state_id == sid] cat(paste("State", current_state, "降水量:", precip, "\n")) print(gt_list[[list_index]]) }
内容的提问来源于stack exchange,提问作者887
相关产品推荐
相关产品推荐

