Поэлементные различия между несколькими столбцами с помощью dplyr - PullRequest
0 голосов
/ 12 мая 2018

Моя цель - создать новые переменные, которые состоят из различий, но повторяются по нескольким столбцам. На базе это безумно просто:

iris[, 6:7] <- iris[, 1:2] - iris[, 3:4]

Есть ли способ добиться этого в dplyr, возможно, с помощью mutate?

Следующий код вычитает третий столбец из 1-го и 2-го:

iris2 <- iris %>%
  mutate_at(1:2, funs(diffs = . - Petal.Length))

но что, если я хочу вычесть 3-й из 1-го и 2-го из 4-го?

Я работаю с довольно большими приложениями данных, так почему бы не предположить, что я пытаюсь сделать это через таблицу из 1000 столбцов - ручной взлом не предпочтителен ...

1 Ответ

0 голосов
/ 12 мая 2018

Вот один из способов использования dplyr::bind_cols и purrr::map2, который оказывается значительно быстрее, чем база при большом количестве столбцов.Я не знаю достаточно о профилировании, чтобы догадаться, почему, так как он кажется немного более запутанным, чем другие варианты.Я не уверен, что это легко сделать с помощью mutate_ глаголов, хотя он открыт для исправления.

РЕДАКТИРОВАТЬ: добавлен параметр с dplyr::do, который является "предполагаемым" способом вычисления, который нене вписывается в функцию mutate.Проблема с mutate состоит в том, что он ожидает создать ровно один столбец.Я думаю, что кроме использования карты для создания отдельных вызовов mutate, которые я не могу себе представить, будет быстрее, это лучший вариант.

library(tidyverse)
set.seed(4321)
df <- matrix(rnorm(1000000), ncol = 1000) %>%
  as_tibble()

microbenchmark::microbenchmark(
  base = df[, 1001:1500] <- df[, 1:500] - df[, 501:1000],
  base2 = df %>% magrittr::inset(, 1001:1500, .[, 1:500] - .[, 501:1000]),
  map =  df %>% bind_cols(map2(.x = .[, 1:500], .y = .[, 501:1000], .f = ~.x - .y)),
  nomap = df %>% bind_cols(.[, 1:500] - .[, 501:1000]),
  do = df %>% do(.[, 1:500] - .[, 501:1000])
)
#> Unit: milliseconds
#>   expr       min        lq      mean    median        uq       max neval
#>   base 32.928171 36.394238 39.362308 37.361149 39.454822 112.76356   100
#>  base2 33.302556 35.500491 38.888530 37.433863 40.207799  84.08674   100
#>    map  4.693637  5.139985  5.967655  5.468398  6.264793  12.20658   100
#>  nomap 23.061348 25.016053 28.598282 26.973913 29.574478  79.97451   100
#>     do 21.906042 23.460822 27.049262 25.135640 26.596373  80.01928   100
#>  cld
#>    c
#>    c
#>  a  
#>   b 
#>   b

Создано в 2018-05-11 пакетом Представить (v0.2.0).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...