如何使用purrr :: map实现行式迭代?
以下是我使用标准行方式应用的方法。
df <- data.frame(a = 1:10, b = 11:20, c = 21:30)
lst_result <- apply(df, 1, function(x){
var1 <- (x[['a']] + x[['b']])
var2 <- x[['c']]/2
return(data.frame(var1 = var1, var2 = var2))
})
然而,这不是太优雅,我宁愿用purrr来做。可能(也可能不会)更快。
答案 0 :(得分:28)
您可以使用pmap
进行逐行迭代。这些列用作您正在使用的任何函数的参数。在你的例子中,你将有一个三参数函数。
例如,pmap
使用匿名函数进行正在进行的工作。列按照它们在数据集中的顺序传递给函数。
pmap(df, function(a, b, c) {
data.frame(var1 = a + b,
var2 = c/2)
} )
您可以使用 purrr 代字号“short-hand”来表示匿名函数,方法是按顺序引用列,前面加上两个点。
pmap(df, ~data.frame(var1 = ..1 + ..2,
var2 = ..3/2) )
如果您希望将这些特定结果作为data.frame而非列表获取,则可以使用pmap_dfr
。
答案 1 :(得分:7)
请注意,您在示例中仅使用了矢量化操作,因此您可以做到:
df %>% dplyr::transmute(var1 = a+b,var2 = c/2)
(或在基础R:transform(df,var1 = a+b,var2 = c/2)[4:5]
)
如果您使用非矢量化函数(例如中位数),则可以使用{@ 1}}作为@aosmith的答案,或使用pmap
。
dplyr::rowwise
速度较慢,软件包维护者建议使用rowwise
系列,但在某些情况下,它可能比map
更容易。当速度不是问题时,我个人仍然使用它:
pmap
(返回严格的未命名列表输出:library(dplyr)
df %>% transmute(var3 = pmap(.,~median(c(..1,..2,..3))))
df %>% rowwise %>% transmute(var3 = median(c(a,b,c)))
)
答案 2 :(得分:2)
您随时可以围绕自己喜欢的功能进行包装。
rmap <- function (.x, .f, ...) {
if(is.null(dim(.x))) stop("dim(X) must have a positive length")
.x <- t(.x) %>% as.data.frame(.,stringsAsFactors=F)
purrr::map(.x=.x,.f=.f,...)
}
应用新功能rmap
( r 向地图)
rmap(df1,~{
var1 <- (.x[[1]] + .x[[2]])
var2 <- .x[[3]]/2
return(data.frame(var1 = var1, var2 = var2))
})
其他信息:(从上到下评估)
df1 <- data.frame(a=1:3,b=1:3,c=1:3)
m <- matrix(1:9,ncol=3)
apply(df1,1,sum)
rmap(df1,sum)
apply(m,1,sum)
rmap(m,sum)
apply(1:10,1,sum) # intentionally throws an error
rmap(1:10,sum) # intentionally throws an error