行方式迭代就像应用purrr一样

时间:2017-10-23 22:24:35

标签: r apply purrr

如何使用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来做。可能(也可能不会)更快。

3 个答案:

答案 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