我对使用父函数中的不可变变量的优雅方式感兴趣.

让我们来看一个例子.

我有一个数据框,上面有周数和它对应的值.

df <- tribble(
  ~week, ~count,
  1, 99.6,
  2, 116, 
  3, 107, 
  4, 125, 
  5, 126, 
  6, 131, 
  7, 149, 
  8, 130, 
  9, 111,
  48, 43.4,
  49, 136, 
  50, 133,
  51, 115, 
  52, 93.3
  )

以下函数向dataframe列添加每周的第一个和最后一个日期.

  add_week_limit_dates <- function(df){
    year_change <- ifelse(any(df$week < 25) && any(df$week > 38), TRUE, FALSE)
    df %>% 
      mutate(week_start = week_to_date(week, 1, year_change),
             week_end = week_to_date(week, 7, year_change))
  }
  
  week_to_date <- function(week, day_of_week, year_change){
    paste0(get_year(week, year_change), 
           "-W", ifelse(week < 10, paste0("0", as.character(week)), week), 
           "-", day_of_week) %>% ISOweek2date()
  }
  
  get_year <- function(week, year_change){
    if(isTRUE(year_change)){
      ifelse(week < 38, year(Sys.Date()), year(Sys.Date()) - 1)
    } else{
      year(Sys.Date())
    }
  }
> add_week_limit_dates(df)
# A tibble: 14 × 4
    week count week_start week_end  
   <dbl> <dbl> <date>     <date>    
 1     1  99.6 2022-01-03 2022-01-09
 2     2 116.  2022-01-10 2022-01-16
 3     3 107.  2022-01-17 2022-01-23
 4     4 125.  2022-01-24 2022-01-30
 5     5 126.  2022-01-31 2022-02-06
 6     6 131.  2022-02-07 2022-02-13
 7     7 149.  2022-02-14 2022-02-20
 8     8 130.  2022-02-21 2022-02-27
 9     9 111.  2022-02-28 2022-03-06
10    48 43.4  2021-11-29 2021-12-05
11    49 136.  2021-12-06 2021-12-12
12    50 133.  2021-12-13 2021-12-19
13    51 115.  2021-12-20 2021-12-26
14    52 93.3  2021-12-27 2022-01-02

那么,我的问题是:是否可以不显式地设置公共变量year_change,并强制子函数在父变量中搜索它?我梦想着下一条路

df %>% 
  mutate(week_start = week_to_date(week, 1),
         week_end = week_to_date(week, 7))

UPD-解决方案

按照建议,我访问了parent.frame(),但请注意it isn't expected one when you use it inside dplyr's methods

 add_week_limit_dates <- function(df){
    year_change <- ifelse(any(df$week < 25) && any(df$week > 38), TRUE, FALSE)
    df$week_start <- week_to_date(df$week, 1)
    df$week_end <- week_to_date(df$week, 7)
    df
  }
  
  week_to_date <- function(week, day_of_week){
    paste0(get_year(week, parent.frame()$year_change), 
           "-W", ifelse(week < 10, paste0("0", as.character(week)), week), 
           "-", day_of_week) %>% ISOweek2date()
  }
  
...

推荐答案

您可以通过被调用函数的parent frame访问调用函数的范围:

mother <- function(){
  year_change = 8
  child()
}

child <- function(){
  print(parent.frame()$year_change)
}

... 或者在函数的即时parent environment中定义它们:

mother <- function(){ ## now the immediate parent environment
  year_change = 8
  child <- function(){
    print(year_change)
  }
  child()
}

... 或者在全球环境中:

year_change = 8 ## the global environment

mother <- function(){
  print(paste("mom's idea of year_change is:", year_change))
  child <- function(){
    print(paste("kid's idea of year_change is:", year_change))
  }
  child()
}


Note that the immediate parent environment outmatches the farther ancestors if variables have the same name.

scoping的详细信息,例如H.Wickham:Advanced R


Edit

羞愧地忘记了利用省略号...参数传递变量的可能性.

example

mother_says <- function(...){
    tell_child(...)
}

tell_child <- function(...){
    args <- list(...)
    print(paste("Mom says:", args$message_to_daughter))
    tell_grandchild(...)
}

tell_grandchild <- function(...){
    args <- list(...)
    print(paste("Granny says:", args$message_to_grandchild))
}

example's output:

## > mother_says(message_to_daughter = "Hi, daughter, how're you?",
## +        message_to_grandchild = "Grandchild, sweetie!"
## +        )
##
## [1] "Mom says: Hi, daughter, how're you?"
## [1] "Granny says: Grandchild, sweetie!"

R相关问答推荐

无法将传奇添加到cowplot多情节中

pickerInput用于显示一条或多条geom_hline,这些线在图中具有不同 colored颜色

在R中替换函数中的特定符号

提取具有连续零值的行,如果它们前面有R中的有效值

Select 季度月值

根据1个变量绘制 colored颜色 发散的 map ,由另一个变量绘制饱和度,ggplot2不工作

如何在科学记数法中显示因子

我如何go 掉盒子图底部的数字?

将全局环境变量的名称分配给列表中的所有元素

在点图上绘制置信度或预测区间ggplot2

创建在文本字符串中发现两个不同关键字的实例的数据框

根据r中每行中的日期序列,使用列名序列创建新列

roxygen2正在处理太多的文件

如何创建一个由一个连续变量和一个因素变量组成的复杂方框图?

修复标签重叠和ggploy内的空间

移除y轴断开的geom_bar图的外框

使用`ggsurvfit::ggsurvfit()`

R直方图存储计算的bin值

为哑铃图准备日期数据

如何计算对偶范数?