2016-12-06 32 views
3

这是一个有点棘手,以显示我的真实数据的问题,但我希望以下的介绍:dplyr ::发生变异:临时贵变量输入到其他几个操作,横行

data_frame(a=c(1,2), b=c(3,4)) %>% 
rowwise %>% 
mutate(c = a*b, d = c-1, e=c+2) %>% 
ungroup 

在上面的例子中当然rowwise是不需要的。

现在让我们假设c的计算既耗时又耗时,c是一个很大的对象而没有向量化。 所以你不需要执行两次,并且希望在每一行计算发生后从内存中清除它。

有没有一个聪明的方法来做到这一点?也许用purrr::map

+0

有人请纠正我,如果我错了,但对象没有矢量化;它是矢量化的操作。在这种情况下,对于矢量'a'和'b',乘法,加法和减法都是矢量化的。因此,对于'c'。如果我说的话完全没有了,那么我可能不会理解这个问题。 – Abdou

+0

是的,我的意思是创建c,d,e的计算/操作应该假设不是为了我的目的而被矢量化的。 –

回答

3

这是使用purrr s invoke_rows的答案。

library(purrr) 

MyDf<-data.frame(a=c(1,2), b=c(3,4)) 
invoke_rows(.d=MyDf, .f=function(a,b){c=a*b 
c(d=c-1, 
e=c+2)}, 
.collate="cols") 

更新

针对@JanStanstrup的评论,如果您有另一列要作为输出的一部分,但不会出现在计算中,你可以这样做:

MyDf<-data.frame(a=c(1,2), b=c(3,4), dummy=c(6,7)) 
invoke_rows(.d=MyDf, .f=function(a,b,...){c=a*b 
c(d=c-1, 
    e=c+2)}, 
.collate="cols") 

这里,dummy和任何其它列经由...作为参数传递到.f功能,但在这种功能不被使用,所以它们只是一直传下去。

+0

太棒了!这样可行。我注意到,如果.d包含未在.f中引用的列,它似乎会出错。 - >'MyDf <-data.frame(a = c(1,2),b = c(3,4),dummy = c(6,7))' - >'unused argument(dummy = .d [[c(3,i)]])'。任何修补程序?当然,我可以将结果与原始数据框架结合起来,但看起来不够优雅。 –

+0

我看到你将未使用的列添加到函数中。虽然这可行,但如果你有很多列,可能会有点混乱。如果添加新列,则更难以维护。也许有一种方法可以将所有这些列名输入到函数中来提取列名称? –

+0

另外我想你可以只包括一列,这是唯一的,你可以加入你的原始表。 –