如何“动态”替换满足谓词的位置?

时间:2017-04-24 17:07:34

标签: r

NB :以下示例使用谓词is.na,但这只是一个示例。我对一般情况感兴趣。 (IOW,谓词可以是is.infinite,或is.nan,或其他任何内容。)

假设某个表达式foo(...)计算到可能包含一些NA值的数据帧,并且该函数barNA - 免费数据帧作为参数。< / p>

避免将无效参数传递给bar的一种方法需要中间分配:

tmp <- foo(...)
tmp[is.na(tmp)] <- 0
bar(tmp)

是否有一些函数baz允许用

做同样的事情
bar(baz(foo(...), is.na, 0, ...))

... 从而避免了中间作业的需要

我知道我总是可以写自己的baz,但是想知道R中是否有类似的东西。

更新

(回应弗兰克的评论。)

实施例

x <- data.frame(K=1001:1005,
                I=3:7,
                R=c(0.1, 0.2, 0.3, 0.4, 0.5),
                B=c(TRUE, FALSE, TRUE, FALSE, TRUE),
                C=c(0.1+0.2i, 0.3+0.4i, 0.5+0.6i, 0.7+0.8i, 0.9+1.0i))

y <- data.frame(K=1001:1003,
                S1=c("a", "b", "c"),
                S2=c("d", "e", "f"),
                stringsAsFactors = FALSE)

使用这些定义,foo(...)可以是表达式

merge(x, y, all = TRUE, by = "K")

对于bar,我认为最简单的事情是人为的,比如

bar <- function (nonas) { stopifnot(!any(is.na(nonas))); nonas }

自制的baz可能是

baz <- function (thing, predicate, value) {
    thing[predicate(thing)] <- value
    thing
}

然后,

bar(merge(x, y, all = TRUE, by = "K"))
## Error: !any(is.na(nonas)) is not TRUE
bar(baz(merge(x, y, all = TRUE, by = "K"), is.na, -1))
##      K I   R     B        C S1 S2
## 1 1001 3 0.1  TRUE 0.1+0.2i  a  d
## 2 1002 4 0.2 FALSE 0.3+0.4i  b  e
## 3 1003 5 0.3  TRUE 0.5+0.6i  c  f
## 4 1004 6 0.4 FALSE 0.7+0.8i -1 -1
## 5 1005 7 0.5  TRUE 0.9+1.0i -1 -1

1 个答案:

答案 0 :(得分:4)

为避免存储foo()的结果,可以做

library(magrittr)
foo() %>% replace(pred(.), 0) %>% bar

此用法记录在?`%>%`

  

将点用作次要用途

     

通常,除了lhs本身的值之外,在rhs调用中还需要lhs的某些属性或属性,例如:行数或列数。在rhs调用中多次使用点占位符是完全有效的,但是通过设计,在嵌套函数调用中使用它时行为略有不同。特别是,如果占位符仅用于嵌套函数调用,则lhs也将作为第一个参数放置!

一般来说,管道可能很慢,所以我不会将它用于任何对性能至关重要的东西。我认为OP的辅助函数baz对于这种情况非常有用,例如bar(baz(foo(), is.na, 0))