У меня обычно есть тиббл с большим количеством столбцов типа character
(между 20 и 30) и только 3-4 столбцами типа numeric
.
Группировка и суммирование числовых столбцов выполняется очень быстро, но мой подход к суммированию символьных столбцов при обеспечении уникальных значений для каждого значения группирования в целом довольно медленный.
Просто интересно, есть ли какой-то более быстрый выход, чем использование paste()
для этого.
library(magrittr)
make_unique <- function(x, sep = "-") {
ifelse(length(x_unique <- unique(x)) == 1, x_unique,
paste(sort(x_unique), collapse = sep))
}
make_unique_2 <- function(x, sep = "-") {
paste(sort(x), collapse = sep)
}
df <- tibble::tribble(
~id, ~country, ~value,
"a", "A", 10,
"a", "B", 20,
"b", "A", 5,
"c", "A", 100,
"c", "B", 1,
"c", "C", 25
)
df %>%
dplyr::group_by(id) %>%
dplyr::summarise_if(is.character, make_unique) %>%
dplyr::ungroup()
#> # A tibble: 3 x 2
#> id country
#> <chr> <chr>
#> 1 a A-B
#> 2 b A
#> 3 c A-B-C
microbenchmark::microbenchmark(
"numeric" = df %>%
dplyr::group_by(id) %>%
dplyr::summarise_if(is.numeric, sum) %>%
dplyr::ungroup(),
"character_1" = df %>%
dplyr::group_by(id) %>%
dplyr::summarise_if(is.character, make_unique) %>%
dplyr::ungroup(),
"character_2" = df %>%
dplyr::group_by(id) %>%
dplyr::summarise_if(is.character, make_unique_2) %>%
dplyr::ungroup()
)
#> Unit: milliseconds
#> expr min lq mean median uq max neval
#> numeric 1.0554 1.24160 1.918480 1.43135 1.90180 8.7733 100
#> character_1 1.1907 1.37530 2.093501 1.60895 2.04235 7.7648 100
#> character_2 1.2255 1.44185 2.474062 1.69260 2.38540 9.4851 100
Создано в 2019-04-05 пакетом представлением (v0.2.1)