按R组显示所有因子水平的计数,即使为零dplyr

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

我有上述代码,它创建了一个随机字母样本。然而,我能否使总结输出显示所有计数级别,即使为零。
当我运行上述代码时,有时会出现20行,有时会出现25行等等。我希望这每次都返回26行。
5个回答

11
在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

本文创建于2019年11月22日,使用reprex软件包(v0.3.0)。

请注意,我们预计所有字母的计数都不为零,但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(),我们将得到1:

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()实际上会将一个m、p、q和x添加到ID中,以确保它至少包含每个字母。


另外,count(var)group_by(var) %>% summarize(n()) 的简写。 - Nick
你是不是想说 summarise(n()) - drT
1
@drT summarizesummarise 两者都可用 - Nick

4
我们可以将“ID”转换为指定了 levelsfactor,然后只需使用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())

谢谢,我用了这个。我在想是否可以对日期做同样的操作。例如,如果“ID”列是一年中的月份,是否可以使用dplyr完成。 - Chinwobble
@Chinwobble 是的,这是可能的。您能提供有关月份如何表示的更多详细信息吗?如果是1:12,则可以使用table(factor(dat$ID, levels = 1:12)) - akrun
它们是来自SQL Server的正确日期时间。因此,它们采用日期对象格式,格式为yyyy-MM-dd - Chinwobble
1
@Chinwobble 然后您需要提取月份,即 table(factor(as.integer(format(as.Date(df1$ID), "%m")), levels = 1:12)) - akrun
@HOSS_JFL 对我来说它运行得很好。我没有像你的输出一样得到1s。也许你也加载了plyr中的summarise并且掩盖了输出结果。如果问题是出在你这边,请从你的解决方案中删除关于我的ID的声明。 - akrun

1
使用akrun的已接受解决方案,我得到了错误的结果。我期望得到一个频率表,其中所有字母的no_rows = 0,除了 "a" 的 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())

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

ID    no_rows
<fct>   <int>
1 a       1
2 b       1
3 c       1
4 d       1
5 e       1
6 f       1
7 g       1
8 h       1
9 i       1
10 j      1
# ... with 16 more rows

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

0

akrun 提供的 tidyverse 解决方案可以按如下方式进行更正:

set.seed(1)
library(tidyverse)
#> Warning: package 'tibble' was built under R version 4.0.5
dat <- data.frame(ID = sample(letters,50,rep=TRUE))
dat %>% 
  mutate(ID=factor(ID, levels = letters)) %>% 
  group_by(ID) %>%
  summarise(no_rows = n()) %>%
  complete(ID, fill = list(no_rows = 0)) %>%
  print.data.frame()
#> `summarise()` ungrouping output (override with `.groups` argument)
#>    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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接