R: dplyr и row_number () не перечисляют как ожидалось - PullRequest
0 голосов
/ 11 октября 2018

Я хочу перечислить каждую запись фрейма данных / таблицы, полученную в результате группировки.Индекс соответствует определенному порядку.Если я использую row_number (), он перечисляет, но внутри группы.Но я хочу, чтобы оно перечислялось без учета прежней группировки.

Вот пример.Для простоты я использовал самый минимальный фрейм данных:

library(dplyr)

df0 <- data.frame( x1 = rep(LETTERS[1:2],each=2)
                 , x2 = rep(letters[1:2], 2)
                 , y = floor(abs(rnorm(4)*10))
)
df0
#   x1 x2  y
# 1  A  a 12
# 2  A  b 24
# 3  B  a  0
# 4  B  b 12

Теперь я сгруппировал эту таблицу:

 df1 <- df0 %>% group_by(x1,x2) %>% summarize(y=sum(y))

Это дает мне объект класса tibble:

 # A tibble: 4 x 3
 # Groups:   x1 [?]
 #   x1    x2        y
 #   <fct> <fct> <dbl>
 # 1 A     a        12
 # 2 A     b        24
 # 3 B     a         0
 # 4 B     b        12

Я хочу добавить номер строки в эту таблицу, используя row_numer ():

 df2 <- df1 %>% arrange(desc(y)) %>% mutate(index = row_number())
 df2
 # A tibble: 4 x 4
 # Groups:   x1 [2]
 #   x1    x2        y index
 #   <fct> <fct> <dbl> <int>
 # 1 A     b        24     1
 # 2 A     a        12     2
 # 3 B     b        12     1
 # 4 B     a         0     2

row_number () перечисляет в предыдущей группе.Это не было моим намерением.Этого можно избежать, чтобы сначала преобразовать tibble в фрейм данных:

 df2 <- df2 %>% as.data.frame() %>% arrange(desc(y)) %>% mutate(index = row_number())
 df2
 #   x1 x2  y index
 # 1  A  b 24     1
 # 2  A  a 12     2
 # 3  B  b 12     3
 # 4  B  a  0     4

Мой вопрос: это поведение предназначено?Если да: разве не очень опасно включать прежнюю обработку данных в таблицу?Какой тип обработки включен?Сейчас я преобразую тиббл в датафрейм, чтобы избежать неожиданных результатов такого рода.

1 Ответ

0 голосов
/ 11 октября 2018

Для уточнения моего комментария: да, сохранение группы предназначено, и во многих случаях полезно.Это опасно, только если вы не понимаете, как работает group_by, и это верно для любой функции.Чтобы отменить group_by, вы звоните ungroup.

Взгляните на group_by документы , поскольку они очень подробны и объясняют, как эта функция взаимодействует с другими, как группируется многоуровневая структура и т. Д. Документы также объясняют, как каждыйвызов summarise удаляет слой группировки - может быть, вы запутались в происходящем.

Например, вы можете группировать по x1 и x2, суммируя y,и создайте номер строки, который даст вам строки в соответствии с x1 (summarise удалил слой группировки, т.е. удаляет группировку x2).Затем разгруппировка позволяет получить номера строк на основе всего фрейма данных.

library(dplyr)

df0 %>%
  group_by(x1, x2) %>%
  summarise(y = sum(y)) %>%
  mutate(group_row = row_number()) %>%
  ungroup() %>%
  mutate(all_df_row = row_number())
#> # A tibble: 4 x 5
#>   x1    x2        y group_row all_df_row
#>   <fct> <fct> <dbl>     <int>      <int>
#> 1 A     a        12         1          1
#> 2 A     b         2         2          2
#> 3 B     a        10         1          3
#> 4 B     b        23         2          4

Вариант использования - я делаю это для работы, вероятно, каждый день - это получение сумм в нескольких группах (опять же, x1и x2), чтобы затем найти доли этих значений в их большей группе (после удаления слоя группировки, это x1) с mutate.Опять же, здесь я разгруппируюсь, чтобы показать общие ресурсы вместо всего фрейма данных.

df0 %>%
  group_by(x1, x2) %>%
  summarise(y = sum(y)) %>%
  mutate(share_in_group = y / sum(y)) %>%
  ungroup() %>%
  mutate(share_all_df = y / sum(y))
#> # A tibble: 4 x 5
#>   x1    x2        y share_in_group share_all_df
#>   <fct> <fct> <dbl>          <dbl>        <dbl>
#> 1 A     a        12          0.857       0.255 
#> 2 A     b         2          0.143       0.0426
#> 3 B     a        10          0.303       0.213 
#> 4 B     b        23          0.697       0.489

Создано в 2018-10-11 пакетом prex (v0.2.1)

...