使用purrr::map()从数据框列表生成ggplot2图表时遇错误求助
问题排查与解决
问题背景
数据定义
df_to_plot <- list(list1 = data.frame(list1 = letters[seq(1, 6)], b = rnorm(n = 6, mean = 7, 1)), list2 = data.frame(list2 = letters[seq(1, 6)], b = rnorm(n = 6, mean = 8, 2)), list3 = data.frame(list3 = letters[seq(1, 6)], b = rnorm(n = 6, mean = 8, 2)))
指定绘图目标
col_list <- c('list1', 'list3')
出错的绘图代码
plots <- function(df_list, col_list){ x = ggplot(df_list, aes(x = as.character(.data[[col_list]]), y = as.numeric(.data[['b']]), fill = as_factor(.data[[col_list]]))) + geom_col() } map(col_list, \(var_list) plots(df_to_plot, var_list))
错误信息
Error in `map()`: ℹ In index: 1. Caused by error in `fortify()`: ! `data` must be a <data.frame>, or an object coercible by `fortify()`, or a valid <data.frame>-like object coercible by `as.data.frame()`. Caused by error in `.prevalidate_data_frame_like_object()`: ! `dim(data)` must return an <integer> of length 2. Run `rlang::last_trace()` to see where the error occurred.
错误原因
- 调用
plots函数时传入了整个列表df_to_plot,但ggplot要求输入单个数据框而非列表,导致数据类型不匹配。 - 函数内尝试用
.data[[col_list]]访问列,但此时df_list是列表结构,无法识别数据框内的列名,进而触发维度验证错误。
修正方案
方案1:拆分列表与绘图逻辑
先筛选目标数据框,再遍历生成图表:
library(ggplot2) library(purrr) # 筛选需要的子数据框 selected_dfs <- df_to_plot[col_list] # 重写绘图函数:接收单个数据框和对应的x轴列名 plots <- function(df, x_col){ ggplot(df, aes(x = as.character(.data[[x_col]]), y = as.numeric(.data[['b']]), fill = as_factor(.data[[x_col]]))) + geom_col() } # 同时遍历数据框和对应的列名 plots_list <- map2(selected_dfs, names(selected_dfs), plots)
方案2:简化遍历逻辑
直接在map中提取目标数据框并绘图:
library(ggplot2) library(purrr) plots_list <- map(col_list, function(var_name){ # 提取当前子数据框 target_df <- df_to_plot[[var_name]] # 针对单个数据框绘图 ggplot(target_df, aes(x = as.character(.data[[var_name]]), y = as.numeric(.data[['b']]), fill = as_factor(.data[[var_name]]))) + geom_col() })
验证说明
两种方案均能生成对应list1和list3的柱状图列表。由于每个子数据框的x轴列名与列表名称完全一致,通过names(selected_dfs)或var_name可精准指定x轴与填充列。
内容的提问来源于stack exchange,提问作者toku_mo
相关产品推荐
相关产品推荐

