管道链中的就地修改

时间:2014-07-11 09:34:41

标签: r magrittr

我正试图在magrittr的管道链中动态修改一些对象。首先尝试:

1:3 %>% (function(x) {x[1] <- 42; x})
#[1] 42  2  3  

使用l的较短选项:

1:3 %>% (l(x ~ {x[1] <- 42; x}))
#[1] 42  2  3

我想知道在不需要定义任何lambda的情况下是否可以实现相同的目标。最简单的方法是什么?我可以使用赋值运算符<-和占位符.吗?类似的东西(注意可读性)

1:3 %>% {.[1] <- 42} # invisible 42 instead

我理解最后的结果是自然的(操作符无形地返回值)。怎么能绕过那个?

3 个答案:

答案 0 :(得分:3)

尝试以下方法:

> 1:3 %>% replace(1, 42)
[1] 42  2  3

答案 1 :(得分:2)

这些管道的主要思想是使事物可读,并在一定程度上坚持功能定义内联撤销。我宁愿在管道外定义一个函数并使用它:

> fidge=function(x,n,v){x[n]=v;x}
> 1:3 %>% fidge(1,42)
[1] 42  2  3

特别是如果您计划在多个地方执行此操作!

如果你真的想在这里打码高尔夫球,那怎么样:

> 1:3 %>% "[<-"(1,42)
[1] 42  2  3

答案 2 :(得分:1)

例如data.framewithin函数可能很有用:

iris %>%
  within({
    Sepal.Length <- 10
    Width.Square <- Sepal.Width^2
  }) 

虽然如果效率和速度是一个问题,也可以使用dplyr::mutate来执行此特定任务。

within也适用于列表:

list(a = 1, b = 2) %>%
  within({
    a = 3
    d = 4
  })

@Spacedman:可能会为extract添加一些别名[(适用于[<-),以使您的高尔夫示例更好:)

编辑:在v1.5中,insetinset2分别添加了[<-[[<-个别名。