【发布时间】: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。以下使用来自purrr 的map 是优雅且有效的:
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))中。