Функция обтекания вокруг purrr::pmap с использованием имен столбцов

Я пытаюсь написать простую функцию, заключающуюся в функцию purrr::pmap_dbl().

У меня есть следующие данные:

df <- data.frame(
          col1 = 1:5, 
          col2 = 2:6, 
          col3 = 3:7
)

И следующая функция:

addfn <- function(x, y){
   x^2 + y
}

Тогда я хотел бы написать такую ​​функцию:

testfn <- function(data, a, b){
    purrr::pmap_dbl(data, function(a, b, ...) addfn(a, b))
}

К несчастью, testfn(df, col1, col2) выдает ошибку в этом случае. Я хотел бы получить тот же вывод, что и вывод, полученный с помощью:

purrr::pmap_dbl(df, function(col1, col2, ...) addfn(col1, col2))

Как это сделать?

3 ответа

Решение

1) testfn Во-первых, обратите внимание, что с помощью testfn из вопроса, что это уже работает:

testfn(unname(df[c("col1", "col3")]))
## [1]  4  8 14 22 32

2) testfn2, и мы можем изменить это следующим образом:

testfn2 <- function(data, ...) {
  data %>% select(...) %>% unname %>% purrr::pmap_dbl(addfn)
}

testfn2(df, col1, col3)
## [1]  4  8 14 22 32

testfn2(df, "col1", "col3")
## [1]  4  8 14 22 32

3) база R Конечно, как уже указывалось, нам не нужно мурлыкать для этого. Это работает в базе R, потому что addfn векторизовано:

with(df, addfn(col1, col3))
## [1]  4  8 14 22 32

или если addfn не были векторизованы тогда:

with(df, mapply(addfn, col1, col3))
## [1]  4  8 14 22 32

и мы могли бы написать эту функцию, используя стандартную оценку:

testfn3 <- function(data, a, b) mapply(addfn, df[[a]], df[[b]])

testfn3(df, "col1", "col3")
## [1]  4  8 14 22 32

или используя нестандартную оценку:

testfn4 <- function(data, ...) eval.parent(substitute(
  with(data, mapply(addfn, ...))
))

testfn4(df, col1, col3)
## [1]  4  8 14 22 32

Вы можете выбрать в свой df, прежде чем использовать его на карте:

library(rlang)
library(dplyr)
library(purrr)
testfn <- function(data, x, y){
  data <- select(data, !!enquo(x), !!enquo(y))
  pmap_dbl(data, ~ addfn(.x, .y))
}

testfn(df, col1, col3) 

Или вы могли бы использовать apply функции.

addfn <- function(x){
  apply(x,1,function(y) y[1]^2 + y[2])
}

addfn(df[,1:2])
[1]  3  7 13 21 31

addfn(df[,2:3])
[1]  7 13 21 31 43
Другие вопросы по тегам