r - 如何从R中的父函数访问变量

标签 r

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

让我们看一个例子。

我有包含星期数及其相应值的数据框。

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
  )

以下函数将每周的第一个日期和最后一个日期添加到数据框列中。

  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

所以,我的问题:是否可以不显式设置公共(public)变量 year_change 并强制子函数在父函数中搜索它?我梦想着下一步

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

UPD - 解决方案

按照建议,我访问了 parent.frame(),但请注意,当您在 dplyr 的方法中使用它时,它不是预期的

 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()
  }
  
...

最佳答案

可以通过被调用函数的父框架访问调用函数的作用域:

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

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

...或在函数的直接父环境之一中定义它们:

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()
}


请注意,如果变量具有相同的名称,则直接父环境将优于更远的祖先环境。

范围界定的详细信息,例如在 H. Wickham:Advanced R


编辑

可耻的是忘记了通过利用省略号...参数来传递变量的可能性。

示例

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))
}

示例的输出:

## > 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 - 如何从R中的父函数访问变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71972517/

相关文章:

r - 当按 df 中具有不同长度组合的另一列在 R 中分组时,获取列中创建的所有组合的计数

r - 如何加速R for循环?

testthat 包的 R 代码覆盖率

r - Sweave 中带有 xtable 的每个页面上的列名

r - 对名称以模式开头的所有列求和的最有效方法是什么?

r - 合并两个没有公共(public)列的数据表

r - 使用基本数据集在 R 和 ggplot 中显示轮廓时出现问题

r - R 是否在内部将数字视为 double ?

r - 从数据框列表中合并数据框

javascript - 重置rhandsontable中的选定范围