#r #dplyr
#r #dplyr
Вопрос:
Я спотыкался о то, что, как мне кажется, я должен знать. Учитывая небольшой фрейм данных, скажем:
d <- tibble(a = c(45, 1, 2, 9), b = c(3, 19, 8, 12))
> d
# A tibble: 4 x 2
a b
<dbl> <dbl>
1 45 3
2 1 19
3 2 8
4 9 12
Я хотел бы изменить некоторые новые переменные в результате вызова toOrdinal (из библиотеки toOrdinal). Я попробовал это:
d %>% mutate(
across(everything(), ~ toOrdinal::toOrdinal(.x), .names = "ord_{col}")
)
Но результаты неверны:
# A tibble: 4 x 4
a b ord_a ord_b
<dbl> <dbl> <chr> <chr>
1 45 3 45th 3rd
2 1 19 1th 19rd
3 2 8 2th 8rd
4 9 12 9th 12rd
Вместо этого я хотел бы видеть:
# A tibble: 4 x 4
a b ord_a ord_b
<dbl> <dbl> <chr> <chr>
1 45 3 45th 3rd
2 1 19 1st 19th
3 2 8 2nd 8th
4 9 12 9th 12th
Те warnings()
, которые обычно очень полезны, не указывают мне, что именно я делаю неправильно.
Любые рекомендации приветствуются!
Ответ №1:
Функция не Vectorized
является . Либо мы используем rowwise
, либо Vectorize
функцию
library(dplyr)
library(toOrdinal)
d %>%
mutate(across(everything(), ~ Vectorize(toOrdinal)(.),.names = "ord_{col}"))
-вывод
# A tibble: 4 x 4
# a b ord_a ord_b
# <dbl> <dbl> <chr> <chr>
#1 45 3 45th 3rd
#2 1 19 1st 19th
#3 2 8 2nd 8th
#4 9 12 9th 12th
Или использовать rowwise
d %>%
rowwise() %>%
mutate(across(everything(), ~ toOrdinal(.), .names = "ord_{col}")) %>%
ungroup
-вывод
# A tibble: 4 x 4
# a b ord_a ord_b
# <dbl> <dbl> <chr> <chr>
#1 45 3 45th 3rd
#2 1 19 1st 19th
#3 2 8 2nd 8th
#4 9 12 9th 12th
Или другой вариант — выполнить последовательное с pmap
помощью from purrr
и связать выходной tibble с исходным набором данных
library(purrr)
library(stringr)
pmap_dfr(d, ~ map_dfr(list(...), toOrdinal)) %>%
rename_all(~ str_c('ord_', .)) %>%
bind_cols(d, .)
-вывод
# A tibble: 4 x 4
# a b ord_a ord_b
# <dbl> <dbl> <chr> <chr>
#1 45 3 45th 3rd
#2 1 19 1st 19th
#3 2 8 2nd 8th
#4 9 12 9th 12th
Комментарии:
1. Ах, да. Спасибо! Я читал о rowwise(), но не применял его на практике. В этом есть большой смысл. Еще раз спасибо вам.