【问题标题】:How to replace positions that satisfy a predicate "on the fly"?如何替换满足“动态”谓词的位置?
【发布时间】:2017-04-25 05:42:36
【问题描述】:

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


假设某个表达式 foo(...) 计算为一个数据框,其中可能包含一些 NA 值,并且该函数 bar 将一个 NA-free 数据框作为参数。

避免将无效参数传递给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

【问题讨论】:

  • 您能创建一个示例tmp 至少考虑一下吗? replace 函数似乎很有可能做到这一点......
  • @Frank:我在帖子中添加了一个示例。另外,我看不出replace 如何避免分配给中间变量(比如我的帖子中的tmp)。
  • 对不起,我不关注。您的帖子似乎已经在bar(baz(foo(), is.na, 0)) 中包含了一个有效的答案,其中foo = function() your code。您是在问某个包中是否已经存在这样的功能?顺便说一句,如果你不喜欢中间变量和括号,这里有foo() %&gt;% replace(pred(.), 0) %&gt;% bar
  • @Frank:是的,我想知道这样的函数是否已经存在,无论是在 R 中还是在某个包中。但是你对%&gt;% 的建议同样好(如果我能让它工作的话!)
  • @Frank:好的,我得到了%&gt;% 的想法。顺便说一句,你知道我可以用一个关键字来搜索 replace(pred(.), 0) 中的单个 . 的文档吗?我试过?`.`等,但一无所获。

标签: r


【解决方案1】:

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

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

这种用法记录在?`%&gt;%`:

将圆点用于次要目的

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-18
    • 1970-01-01
    • 2019-08-20
    • 1970-01-01
    • 1970-01-01
    • 2017-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多