Работает ли dplyr :: mutate со столбцами в стиле записи? - PullRequest
2 голосов
/ 14 января 2020

Я недавно тестировал пакет vctrs, особенно то, что они недавно называют объектами в стиле записи, и мне интересно, есть ли способ заставить их играть хорошо с dplyr :: mutate. В настоящее время, когда dplyr :: mutate выдает мне ошибку о длине объектов всякий раз, когда я пытаюсь их использовать.

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

library("vctrs")
library("dplyr")
new_rational <- function(n = integer(), d = integer()) {
  vec_assert(n, ptype = integer())
  vec_assert(d, ptype = integer())

  new_rcrd(list(n = n, d = d), class = "vctrs_rational")
}

format.vctrs_rational <- function(x, ...) {
  n <- field(x, "n")
  d <- field(x, "d")

  out <- paste0(n, "/", d)
  out[is.na(n) | is.na(d)] <- NA

  out
}

Пока все хорошо, но когда я пытаюсь создать столбец рациональных чисел, используя dplyr :: mutate, я получаю сообщение об ошибке

df <- data.frame(n = c(1L, 2L, 3L), d = 2L)
df %>% dplyr::mutate(frac = new_rational(n, d))
#> Error: Column `frac` must be length 3 (the number of rows) or one, not 2

Но создание столбца в базе R работает просто отлично:

df$rational <- new_rational(df$n, df$d)
df
#>   n d rational
#> 1 1 2      1/2
#> 2 2 2      2/2
#> 3 3 2      3/2

Есть ли какая-то хитрость, чтобы заставить это работать, используя dplyr :: mutate, или это просто невозможно?

1 Ответ

1 голос
/ 14 января 2020

new_rational возвращает вывод в виде списка, как вы можете видеть ниже

> typeof(new_rational(n=1L, d=2L))
[1] "list"

, поэтому мы можем получить вывод в виде списка, используя map или as.list "предложение Ронака" затем используйте unnest.

df %>% dplyr::mutate(frac = purrr::map2(n,d, ~new_rational(.x, .y))) %>% 
       tidyr::unnest(cols=c(frac))
# A tibble: 3 x 3
      n     d       frac
  <int> <int> <vctrs_rt>
1     1     2        1/2
2     2     2        2/2
3     3     2        3/2
...