Нежелательный _1 в обобщении dplyr()

#r #dplyr

Вопрос:

Вот пример сводной таблицы в dplyr:

 library(dplyr)

category <- c('A', 'A', 'A', 'B', 'B')
col1 <- c(1, 1, 0, 0, 1)
col2 <- c(1, 0, 1, 1, 1)
tbl <- as_tibble(data.frame(category, col1, col2))

sum_tbl <- tbl %>%
    group_by(category) %>%
    summarize(across(everything(), list(sum)))
print(sum_tbl)
 

Это приводит к

 # A tibble: 2 x 3
category col1_1 col2_1
<chr>     <dbl>  <dbl>
1 A           2      2
2 B           1      2
 

Я не понимаю, откуда берутся эти _1 колонки. Как мне от них избавиться? Имейте в виду, что это игрушечный пример, а мой фактический tbl содержит сотни столбцов.

Комментарии:

1. Я думаю, это потому, что вы используете список функций для .fns . Попробуйте использовать across(everything(), sum) вместо этого.

Ответ №1:

Как упоминал @aosmith, это связано с тем, что вы использовали list() при применении функции. list() обычно используется для применения более чем одной функции, где _1 суффикс для 1-й функции, _2 для второй функции и так далее.

 library(dplyr)

tbl %>%
  group_by(category) %>%
  summarize(across(everything(), list(sum, mean)))

#  category col1_1 col1_2 col2_1 col2_2
#  <chr>     <dbl>  <dbl>  <dbl>  <dbl>
#1 A             2  0.667      2  0.667
#2 B             1  0.5        2  1    
 

Или используйте именованный список, чтобы получить значимые имена столбцов.

 tbl %>%
  group_by(category) %>%
  summarize(across(everything(), list(sum = sum, mean = mean)))

# category col1_sum col1_mean col2_sum col2_mean
#  <chr>       <dbl>     <dbl>    <dbl>     <dbl>
#1 A               2     0.667        2     0.667
#2 B               1     0.5          2     1    
 

Если вы хотите применить одну функцию, вы можете сделать это напрямую.

 tbl %>%
  group_by(category) %>%
  summarize(across(.fns = sum))

#  category  col1  col2
#  <chr>    <dbl> <dbl>
#1 A            2     2
#2 B            1     2
 

Ответ №2:

Мы могли бы изменить .names , если мы добавляем list

 library(dplyr)
tbl %>%
    group_by(category) %>%
     summarize(across(everything(), list(sum), .names = "{.col}"))
# A tibble: 2 x 3
  category  col1  col2
  <chr>    <dbl> <dbl>
1 A            2     2
2 B            1     2