稍后在管道中访问结果

稍后在管道中访问结果

我正在尝试创建在管道中的每一步打印数据集中排除的行数的函数。

像这样的东西:

iris %>% 
    function_which_save_nrows_and_return_the_data() %>% 
    filter(exclude some rows) %>% 
    function_which_prints_difference_in_rows_before_after_exlusion_and_returns_data %>% 
    function_which_save_nrows_and_return_the_data() %>% 
    function_which_prints_difference_in_rows_before_after_exlusion_and_returns_data  ...etc

这些是我尝试过的功能:

n_before = function(x) {assign("rows", nrow(x), .GlobalEnv); return(x)}

n_excluded = function(x) { 
    print(rows - nrow(x))
    return(x)
}

这成功地保存了对象行:

但是,如果我再添加两个链接,则不会保存该对象:

那么如何在管道之后创建和访问行对象呢?

回答

这是由于 R 的惰性求值造成的。即使不使用管道也会发生。请参阅下面的代码。在该代码的参数n_excludedfilter(n_before(iris), Species != 'setosa')在该点rows在使用print该说法并没有得到来自中引用的语句n_excluded,因此整个参数将不进行了评估,所以rows还不存在。

if (exists("rows")) rm(rows)  # ensure rows does not exist
n_excluded(filter(n_before(iris), Species != 'setosa'))
## Error in h(simpleError(msg, call)) : 
##   error in evaluating the argument 'x' in selecting a method for function 
##   'print': object 'rows' not found

要解决这个问题

1)我们可以在print语句之前强制 x 。

n_excluded = function(x) { 
  force(x)
  print(rows - nrow(x))
  return(x)
}

2)或者,我们可以使用 magrittr 顺序管道来保证腿按顺序运行。magrittr 使它可用,但没有为其提供运算符,但我们可以将它分配给这样的运算符。

`%s>%` <- magrittr::pipe_eager_lexical
iris %>%
  n_before() %>%
  filter(Species != 'setosa') %s>%  # note use of %s>% on this line
  n_excluded()

magrittr 开发人员表示,如果有足够的需求,他会将其添加为运算符,因此您可能希望将此类请求添加到github 上的magrittr issue #247。


以上是稍后在管道中访问结果的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>