在 R 中,如何在绘图的两个内部函数之间传递数据帧/小标题,然后保存绘图?

Posted

技术标签:

【中文标题】在 R 中,如何在绘图的两个内部函数之间传递数据帧/小标题,然后保存绘图?【英文标题】:In R how to pass dataframe/tibble between two inner functions for a plot and then save the plot? 【发布时间】:2020-09-28 09:05:11 【问题描述】:

我创建了一个外部函数来运行 3 个内部函数进行数据预处理,然后绘制并保存它。

面临的问题与下一个内部函数共享 1 个内部函数的数据帧输出

library(tidyverse)
library(glue)

gapminder <- read.csv("https://raw.githubusercontent.com/swcarpentry/r-novice-gapminder/gh-pages/_episodes_rmd/data/gapminder-FiveYearData.csv")

外层函数

fn_run_all <-function(bench_country = India, year_start = 1952, year_end = 2007)
  
  
  year_start = year_start
  year_end = year_end
  
  # Function1 for PreProcess Benchmarked Country
  fn_benchmark_country(bench_country) 

  # Function2 to PreProcess dates & pass df to function3 to plot  
  Plot_final <- fn_year_filter(gapminder_joined, year_start, year_end) %>% 
  
                # function 3 to plot  
                fn_create_plot(., year_start, year_end, bench_country)
  
  
  # Saving plot
  jpeg(file="gdp_benchmarked_FinalPlot.jpeg", width = 1400, height = 1800)
  Plot_final
  dev.off()
  
  # Printing Plot
  Plot_final
  

fn_run_all(India, 1952, 2002)

问题 1

如果我不输出数据帧,即第一个函数 fn_benchmark_country()gapminder_joinedglobal,那么我在函数 2 fn_year_filter() 中出现错误。

但是当我将 function1 的输出(即gapminder_joined)推送到Global 时,它就可以工作了。

Is it necessary to make it global even when I am returning it within the outer function or there is some other alternative way?

Function1 代码参考

fn_benchmark_country  <- function(bench_country = India)
  
  bench_country = enquo(bench_country)

  gapminder_benchmarked_wider <- gapminder %>% 
                                  select(country, year, gdpPercap) %>% 
                                  pivot_wider(names_from = country, values_from = gdpPercap) %>% 
                                  arrange(year) %>% 
                                  # map_dbl( ~.x - India )
                                  mutate(across(-1, ~ . - !!bench_country))
                                  
  # Reshaping back to Longer
  gapminder_benchmarked_longer <- gapminder_benchmarked_wider %>% 
                                  pivot_longer(cols = !year, names_to = "country", values_to = "benchmarked") 
 
  # Joining tables
  gapminder_joined <- left_join(x = gapminder, y = gapminder_benchmarked_longer, by = c("year","country"))

  # converting to factor
  gapminder_joined$country <- as.factor(gapminder_joined$country)
  
  # gapminder_joined <<- gapminder_joined
  return(gapminder_joined)

在上面的代码中,如果我取消注释倒数第二行,那么它可以工作。

Function2 代码参考

fn_year_filter  <- function(gapminder_joined, year_start, year_end)

                              gapminder_joined %>% 
                              filter(year %in% c(year_start,year_end)) %>% 
                              
                              arrange(country, year) %>% 
                              
                              group_by(country) %>% 
                              
                              mutate(benchmark_diff = benchmarked[2] - benchmarked[1],
                                     max_pop = max(pop)) %>% 
                              
                              ungroup() %>% 
                              
                              arrange(benchmark_diff) %>% 
                              
                              filter(max_pop > 30000000) %>% 
                              
                              mutate(country = droplevels(country)) %>% 
                              select(country, year, continent, benchmarked, benchmark_diff) %>% 
                                
                              # --- 
                              mutate(country = fct_inorder(country)) %>% 
                              
                              group_by(country) %>% 
                                
                              mutate(benchmarked_end = benchmarked[2],
                                     benchmarked_start = benchmarked[1]  ) %>% 
                              
                              ungroup() 

  

【问题讨论】:

当然我会从这里删除第二个! 【参考方案1】:

不要从函数内部更新变量。您采用的方法是正确的,因此无需使用&lt;&lt;-,保持fn_benchmark_country 不变。尝试将返回的数据框保存在函数中。

fn_run_all <-function(bench_country = India, year_start = 1952, year_end = 2007)
  
  # Function1 for PreProcess Benchmarked Country
  gapminder_joined <- fn_benchmark_country(bench_country) 
  # Function2 to PreProcess dates & pass df to function3 to plot  
  Plot_final <- fn_year_filter(gapminder_joined, year_start, year_end) %>% 
    # function 3 to plot  
   fn_create_plot(., year_start, year_end, bench_country)
   #...rest of the code
   #...
   #...
  

【讨论】:

以上是关于在 R 中,如何在绘图的两个内部函数之间传递数据帧/小标题,然后保存绘图?的主要内容,如果未能解决你的问题,请参考以下文章

R:将表达式传递给内部函数

如何纠正 R 函数中的变异和过滤错误

两个数据帧之间的 T 检验并按 R 中的相似行分组

如果日期介于第二个数据帧中的两个日期之间,则 r 标记第一个数据帧中的行

如何将数据帧传递到气流任务的临时表中

R语言绘图:复杂散点图绘制