dplyr summaze: эквивалент «.drop = FALSE» для сохранения групп с нулевой длиной в выводе

При использовании summarise с plyr ddply, пустые категории по умолчанию удаляются. Вы можете изменить это поведение, добавив .drop = FALSE. Однако это не работает при использовании summarise с dplyr. Есть ли другой способ сохранить пустые категории в результате?

Вот пример с поддельными данными.

library(dplyr)

df = data.frame(a=rep(1:3,4), b=rep(1:2,6))

# Now add an extra level to df$b that has no corresponding value in df$a
df$b = factor(df$b, levels=1:3)

# Summarise with plyr, keeping categories with a count of zero
plyr::ddply(df, "b", summarise, count_a=length(a), .drop=FALSE)

  b    count_a
1 1    6
2 2    6
3 3    0

# Now try it with dplyr
df %.%
  group_by(b) %.%
  summarise(count_a=length(a), .drop=FALSE)

  b     count_a .drop
1 1     6       FALSE
2 2     6       FALSE

Не совсем то, на что я надеялся. Существует ли метод dplyr для достижения того же результата, что и для .drop=FALSE в plyr?

82 голоса | спросил eipi10 20 MaramThu, 20 Mar 2014 07:52:09 +04002014-03-20T07:52:09+04:0007 2014, 07:52:09

3 ответа


0

Проблема все еще остается открытой, но тем временем, тем более что ваши данные уже учтены, вы можете использовать complete из "tidyr". "чтобы получить то, что вы могли искать:

library(tidyr)
df %>%
  group_by(b) %>%
  summarise(count_a=length(a)) %>%
  complete(b)
# Source: local data frame [3 x 2]
# 
#        b count_a
#   (fctr)   (int)
# 1      1       6
# 2      2       6
# 3      3      NA

Если вы хотите, чтобы значение замены было нулевым, вам нужно указать это с помощью fill:

df %>%
  group_by(b) %>%
  summarise(count_a=length(a)) %>%
  complete(b, fill = list(count_a = 0))
# Source: local data frame [3 x 2]
# 
#        b count_a
#   (fctr)   (dbl)
# 1      1       6
# 2      2       6
# 3      3       0
ответил A5C1D2H2I1M1N2O1R2T1 18 MarpmFri, 18 Mar 2016 22:07:51 +03002016-03-18T22:07:51+03:0010 2016, 22:07:51
0

Решение dplyr:

Сначала создайте сгруппированный df

by_b <- tbl_df(df) %>% group_by(b)

затем мы суммируем эти уровни путем подсчета с помощью n()

res <- by_b %>% summarise( count_a = n() )

затем мы объединяем наши результаты в фрейм данных, который содержит все уровни факторов:

expanded_res <- left_join(expand.grid(b = levels(df$b)),res)

наконец, в этом случае, так как мы смотрим на счетчики, значения NA изменяются на 0.

final_counts <- expanded_res[is.na(expanded_res)] <- 0

Это также может быть реализовано функционально, см. ответы: Добавить строки в сгруппированные данные с помощью dplyr?

Хак:

Я думал, что опубликую ужасный хак, который работает в этом случае ради интереса. Я серьезно сомневаюсь, что вы когда-либо действительно будете это делать, но это показывает, как group_by() генерирует атрибуты, как если бы df$b был символьным вектором, а не фактором с уровнями. Кроме того, я не претендую на то, что понимаю это должным образом - но я надеюсь, что это поможет мне учиться - это единственная причина, по которой я публикую это!

by_b <- tbl_df(df) %>% group_by(b)

определите значение "вне границ", которое не может существовать в наборе данных.

oob_val <- nrow(by_b)+1

измените атрибуты на "трюк" summarise():

attr(by_b, "indices")[[3]] <- rep(NA,oob_val)
attr(by_b, "group_sizes")[3] <- 0
attr(by_b, "labels")[3,] <- 3

сделать резюме:

res <- by_b %>% summarise(count_a = n())

индексировать и заменять все вхождения oob_val

res[res == oob_val] <- 0

который дает предполагаемое:

> res
Source: local data frame [3 x 2]

b count_a
1 1       6
2 2       6
3 3       0
ответил npjc 24 Maypm14 2014, 21:11:03
0

это не совсем то, что было задано в вопросе, но по крайней мере для этого простого примера вы можете получить тот же результат, используя xtabs, например:

используя dplyr:

df %.%
  xtabs(formula = ~ b) %.%
  as.data.frame()

или короче:

as.data.frame(xtabs( ~ b, df))

результат (одинаковый в обоих случаях):

  b Freq
1 1    6
2 2    6
3 3    0
ответил docendo discimus 5 Maypm14 2014, 22:46:08

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132