在R中将变量名作为参数从外部函数传递到内部函数时出现问题吗?

问题描述

我试图使一个过程自动化,并创建一个外部函数来运行几个较小的内部函数,但是以function作为参数的variable names会导致错误

当我自己运行以下功能时,它将正常工作:

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

################ fn_benchmark_country ################

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) %>% 
                                  
                                  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)
  
  return(gapminder_joined)  
}

################ ----------------------------- ################

# Calling function
fn_benchmark_country(Vietnam) 

country     year     pop  continent  lifeExp    gdpPercap   benchmarked

Afghanistan 1952    8425333 Asia    28.80100    779.4453    232.879565
Afghanistan 1957    9240934 Asia    30.33200    820.8530    230.791034

但是当我在外部函数中运行它时,它给了我错误

fn_run_all <-function(bench_country = India,year_start = 1952,year_end = 2007){
  
  bench_country = bench_country
  year_start = year_start
  year_end = year_end
  
  fn_benchmark_country(bench_country)
}

fn_run_all()

Error in fn_run_all() : object 'India' not found

如果我将enquo添加到自变量中,则仍然会出现错误,如下所示”

fn_run_all <-function(bench_country = India,year_end = 2007){
  
  bench_country = enquo(bench_country)
  year_start = year_start
  year_end = year_end
  
  fn_benchmark_country(bench_country)
}

fn_run_all()

Error: Problem with `mutate()` input `..1`. x Base operators are not defined for quosures. Do you need to unquote the quosure? # Bad: lhs - myquosure # Good: lhs - !!myquosure i Input `..1` is `across(-1,~. - bench_country)`.

不确定如何解决此问题,将不胜感激!

从此处添加新的相关问题

现在由于上一次内部函数调用fn_create_plot()

而出现错误

由于在情节的bench_country中使用了creating dynamic subtitle,因此发生了相同类型的问题,但是这次我使用了{{}},但仍然出现问题

fn_run_all <-function(bench_country = India,year_end = 2007){
  

  year_start = year_start
  year_end = year_end
  
  fn_benchmark_country({{bench_country}})
  
  fn_year_filter(gapminder_joined,year_start,year_end) %>% 
  
  fn_create_plot(.,year_end,{{bench_country}})
}

fn_run_all(Vietnam,1967,2002)

Error in sprintf("Benchmarked %i in blue line \nFor Countries with pop > 30000000 \n(Chart created by ViSa)",: object 'Vietnam' not found

功能代码参考

################ fn_create_plot ################
  
fn_create_plot <- function(df,bench_country ){

                  
                  
                  # plotting
                      ggplot(df) +
                        
                      geom_vline(xintercept = 0,col = "blue",alpha = 0.5) +
    
                      geom_label( label="India - As Benchamrking line",x=0,y="United States",label.padding = unit(0.55,"lines"),# Rectangle size around label
                        label.size = 0.35,color = "black") +
                      
                      geom_segment(aes(x = benchmarked_start,xend = benchmarked_end,y = country,yend = country,col = continent),alpha = 0.5,size = 7) +
                      
                      geom_point(aes(x = benchmarked,size = 9,alpha = .6) +
                      
                      geom_text(aes(x = benchmarked_start + 8,label = paste(country,round(benchmarked_start))),col = "grey50",hjust = "right") +
                      
                      geom_text(aes(x = benchmarked_end - 4.0,label = round(benchmarked_end)),hjust = "left") +
                    
                      
                      # scale_x_continuous(limits = c(20,85)) +
                      
                      scale_color_brewer(palette = "Pastel2") +
                      
                      labs(title = sprintf("GdpPerCapita Differenece with India (Starting point at %i and Ending at %i)",year_end),subtitle = sprintf("Benchmarked %i in blue line \nFor Countries with pop > 30000000 \n(Chart created by ViSa)",bench_country),col = "Continent",x = sprintf("GdpPerCap Difference at %i & %i",year_end) ) +
                      
                  # background & theme settings
                      theme_classic() +
                      
                      theme(legend.position = "top",axis.line = element_blank(),axis.ticks = element_blank(),axis.text = element_blank()
                            )
}

################ ----------------------------- ################

解决方法

使用enquo()时,在函数中调用有问题的变量时,也需要使用!!。这有效:

fn_run_all <-function(bench_country = India,year_start = 1952,year_end = 2007){
  
  bench_country = enquo(bench_country)
  year_start = year_start
  year_end = year_end
  
  fn_benchmark_country(!! bench_country)
}

fn_run_all()

您也可以将enquo()!!替换为隧道{{ }}

fn_run_all <-function(bench_country = India,year_end = 2007){
  
  year_start = year_start
  year_end = year_end
  
  fn_benchmark_country({{ bench_country }})
}

fn_run_all()

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...