【问题标题】:R: Count categories in each column when not all categories appearR:当并非所有类别都出现时,计算每列中的类别
【发布时间】:2017-05-03 14:03:03
【问题描述】:

带有character 列的简单data.frame

df <- data.frame(x = c("a", "b", "c", "c"), y = c("a", "b", "b", "c"))

假设我希望计算每一列的类别,并快速返回另一个data.frame。以下使用来自purrrmap 是优雅且有效的:

df %>%
  map(table) %>%
  Reduce(cbind, .) %>%
  data.frame() %>%
  set_names(c("x", "y"))

  x y
a 1 1
b 1 2
c 2 1

但是。当并非所有类别都出现在每列中时该怎么办?示例:

df2 <- data.frame(x = c("a", "b", "b"), y = c("a", "a", "a"))

我希望y 列中b 的计数为0。但我明白了:

df2 %>%
  map(table) %>%
  Reduce(cbind, .) %>%
  data.frame() %>%
  set_names(c("x", "y"))

  x y
a 1 3
b 2 3

甚至没有警告!我猜这是因为cbind 的习惯是回收一列的元素以匹配另一列的长度。我尝试使用qpcR:::cbind.na 至少获取缺失类别的NA 值,稍后我可以将其转换为0,但出现此错误:

Error in matrix(, maxRow - nrow(x), ncol(x)) : 
  invalid 'ncol' value (too large or NA)

有什么好的快速解决方案,最好来自tidyverse 包集?

更新:

对于我们知道所有类别都在所有列中的第一种情况:

df %>% dmap(function(x) as.numeric(table(x)))

可能更优雅。

【问题讨论】:

  • 在基础 R 中,以下将起作用。 sapply(df2, function(i) table(factor(i, levels=levels(unlist(df2)))))factor 用于包含所有可用级别,包含在levels(unlist(df2)) 中。

标签: r tidyverse purrr


【解决方案1】:

您可以使用 tidyr 中的 gather()spread(),中间使用 dplyr 的 count()

library(dplyr)
library(tidyr)

df2 <- data_frame(x = c("a", "b", "b"), y = c("a", "a", "a"))

df2 %>%
  gather(key, value) %>%
  count(key, value) %>%
  spread(key, n, fill = 0)

结果:

  value     x     y
* <chr> <dbl> <dbl>
1     a     1     3
2     b     2     0

spread() 中的 fill = 0 是导致 b/y 对为 0 的原因。

【讨论】:

  • 谢谢。你。不错。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-09
相关资源
最近更新 更多