作者:SREFLANKCWF | 来源:互联网 | 2023-09-11 19:23
稍后在管道中访问结果
我正在尝试创建在管道中的每一步打印数据集中排除的行数的函数。
像这样的东西:
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_excluded
是filter(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。