R:purrr:使用 pmap 进行行操作,但这次涉及很多列

dai*_*ain 3 r rows parameter-passing pmap purrr

这不是问题的重复,例如Row-wise iteration like apply with purrr

我了解如何使用pmap()对数据框进行逐行操作:

library(tidyverse)

df1 = tribble(~col_1, ~col_2, ~col_3,
               1,      5,      12,
               9,      3,      3,
               6,     10,     7)

foo = function(col_1, col_2, col_3) {
  mean(c(col_1, col_2, col_3))
}

df1 %>% pmap_dbl(foo)
Run Code Online (Sandbox Code Playgroud)

foo这给出了应用于每一行的函数:

[1] 6.000000 5.000000 7.666667
Run Code Online (Sandbox Code Playgroud)

但是,当我有多个列时,这会变得非常笨拙,因为我必须显式地将它们全部传递。如果我说,我的数据框中有 8 列df2,并且我想应用一个bar可能涉及其中每一列的函数,该怎么办?

set.seed(12345)
df2 = rnorm(n=24) %>% matrix(nrow=3) %>% as_tibble() %>%
  setNames(c("col_1", "col_2", "col_3", "col_4", "col_5", "col_6", "col_7", "col_8"))

bar = function(col_1, col_2, col_3, col_4, col_5, col_6, col_7, col_8) {
  # imagine we do some complicated row-wise operation here
  mean(c(col_1, col_2, col_3, col_4, col_5, col_6, col_7, col_8))
}

df2 %>% pmap_dbl(bar)
Run Code Online (Sandbox Code Playgroud)

给出:

[1]  0.45085420  0.02639697 -0.28121651
Run Code Online (Sandbox Code Playgroud)

这显然是不够的——我必须bar为每一列添加一个新的参数。需要输入大量内容,这使得代码的可读性较差且更加脆弱。似乎应该有一种方法让它接受一个参数x,然后通过等等访问我想要的变量。x$col_1或者无论如何比上面更优雅的东西。有什么方法可以使用 purrr 清理这段代码吗?

Bri*_*ian 6

一旦它们出现在您的函数中,您就可以使用...它们list

dot_tester <- function(...) {
  dots <- list(...)
  dots$Sepal.Length + dots$Petal.Width
}

purrr::pmap(head(iris), dot_tester)
Run Code Online (Sandbox Code Playgroud)
[[1]]
[1] 5.3

[[2]]
[1] 5.1

[[3]]
[1] 4.9

[[4]]
[1] 4.8

[[5]]
[1] 5.2

[[6]]
[1] 5.8
Run Code Online (Sandbox Code Playgroud)

但是,这不会改变您的代码“脆弱”,因为您仍然明确且准确地需要将列名称与函数中的名称相匹配。好处是不必在<- function()电话会议中列出它们。