R组即使在零dplyr时也显示所有因子水平的计数

时间:2017-02-03 06:16:18

标签: r dplyr

set.seed(1)
dat <- data.frame(ID = sample(letters,50,rep=TRUE))
dat %>% 
  group_by(ID) %>%
  summarise(no_rows = length(ID))

我有上面的代码,它创建了一个随机的字母样本。但是,即使存在零,我也可以使汇总输出显示所有计数级别。

当我运行上面的代码时,我有时会得到20行,有时候会得到25行等等。 我希望每次都返回26行。

4 个答案:

答案 0 :(得分:4)

我们可以转换ID&#39; ID&#39;指定factorlevels并使用table

table(factor(dat$ID, levels = letters))

或者使用与tidyverse

相同的内容
library(tidyverse)
dat %>% 
  mutate(ID=factor(ID, levels = letters)) %>% 
  complete(ID) %>%
  group_by(ID) %>%
  summarise(no_rows = n())

答案 1 :(得分:1)

这也有效:

set.seed(1)
dat <- data.frame(ID = sample(letters,50,rep=TRUE))
levels(dat$ID) <- letters
as.data.frame(dat %>% xtabs(formula = ~ ID))
#   ID Freq
#1   a    2
#2   b    1
#3   c    1
#4   d    1
#5   e    2
#6   f    3
#7   g    2
#8   h    1
#9   i    4
#10  j    2
#11  k    4
#12  l    1
#13  m    2
#14  n    1
#15  o    3
#16  p    3
#17  q    3
#18  r    1
#19  s    5
#20  t    2
#21  u    1
#22  v    2
#23  w    2
#24  x    1
#25  y    0
#26  z    0

答案 2 :(得分:0)

使用akrun接受的解决方案会得到错误的结果。我希望出现一个频率表,其中所有字母的no_rows = 0除外,除了“ a”的no_rows =1。

Private Sub Worksheet_Change(ByVal Target As Range)

相反,我得到一个频率表,其中所有字母的no_rows = 1:

library(tidyverse)
set.seed(1)
dat <- data.frame(ID = "a")
dat %>% 
  dplyr::mutate(ID=factor(ID, levels = letters)) %>% 
  tidyr::complete(ID) %>%
  dplyr::group_by(ID) %>%
  dplyr::summarise(no_rows = n())

答案 3 :(得分:0)

在akrun接受的答案中,table()有效,但是tidyverse答案给出的计数不准确(请参见下文)。而是使用.drop = FALSE选项:

library(tidyverse)
set.seed(1)
dat <- data.frame(ID = sample(letters,50,rep=TRUE))
dat %>%
  mutate(ID = factor(ID, levels = letters)) %>%
  count(ID, name = "no_rows", .drop = F) %>%
  print.data.frame()
#>    ID no_rows
#> 1   a       3
#> 2   b       2
#> 3   c       1
#> 4   d       1
#> 5   e       3
#> 6   f       3
#> 7   g       2
#> 8   h       1
#> 9   i       2
#> 10  j       5
#> 11  k       1
#> 12  l       3
#> 13  m       0
#> 14  n       3
#> 15  o       3
#> 16  p       0
#> 17  q       0
#> 18  r       1
#> 19  s       1
#> 20  t       3
#> 21  u       3
#> 22  v       1
#> 23  w       2
#> 24  x       0
#> 25  y       5
#> 26  z       1

reprex package(v0.3.0)于2019-11-22创建

请注意,我们期望除m,p,q和x以外的所有字母的计数都为非零:

set.seed(1)
dat <- data.frame(ID = sample(letters,50,rep=TRUE))
levels(dat$ID)
#>  [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "n" "o" "r" "s" "t"
#> [18] "u" "v" "w" "y" "z"

但是如果我们使用complete()则会得到一个:

set.seed(1)
dat <- data.frame(ID = sample(letters,50,rep=TRUE))
dat %>% 
  mutate(ID=factor(ID, levels = letters)) %>% 
  complete(ID) %>%
  group_by(ID) %>%
  summarise(no_rows = n()) %>%
  print.data.frame()
#>    ID no_rows
# ...
#> 12  l       3
#> 13  m       1  # should be 0
#> 14  n       3
#> 15  o       3
#> 16  p       1  # should be 0
#> 17  q       1  # should be 0
#> 18  r       1
#> 19  s       1
#> 20  t       3
#> 21  u       3
#> 22  v       1
#> 23  w       2
#> 24  x       1  # should be 0
#> 25  y       5
#> 26  z       1

这是因为complete()实际上向ID添加了一个m,p,q和x,因此它至少包含每个字母之一。