![](/img/trans.png)
[英]In R how do I sum values in a data.table column aggregated by two character columns, with matrix with colnames and rownames equal to strings output?
[英]How do I sum recurring values according to a level in a column and output a table of counts?
我是R的新手,我的数据看起来像这样:
categories <- c("A","B","C","A","A","B","C","A","B","C","A","B","B","C","C")
animals <- c("cat","cat","cat","dog","mouse","mouse","rabbit","rat","shark","shark","tiger","tiger","whale","whale","worm")
dat <- cbind(categories,animals)
有些动物根据类别重复。 例如,“cat”出现在所有三个类别A,B和C.
我喜欢我的新数据帧输出看起来像这样:
A B C count
1 1 1 1
1 1 0 2
1 0 1 0
0 1 1 2
1 0 0 2
0 1 0 0
0 0 1 2
0 0 0 0
A,B和C下的数字1表示动物出现在该类别中,0表示动物未出现在该类别中。 例如,第一行在所有三个类别中都有1。 第一行的计数为1,因为“cat”是每个类别中唯一重复的动物。
R中有一个函数可以帮助我实现这个目标吗? 先感谢您。
我们可以使用table
来创建categories
和animals
的交叉列表,转置,转换为data.frame, group_by
所有categories
并计算每个组合的频率:
library(dplyr)
library(tidyr)
as.data.frame.matrix(t(table(dat))) %>%
group_by_all() %>%
summarize(Count = n())
结果:
# A tibble: 5 x 4
# Groups: A, B [?]
A B C Count
<int> <int> <int> <int>
1 0 0 1 2
2 0 1 1 2
3 1 0 0 2
4 1 1 0 2
5 1 1 1 1
编辑 (感谢@C.Braun)。 以下是如何包含零A,B,C组合:
as.data.frame.matrix(t(table(dat))) %>%
bind_rows(expand.grid(A = c(0,1), B = c(0,1), C = c(0,1))) %>%
group_by_all() %>%
summarize(Count = n()-1)
或者complete
按照@Ryan的建议:
as.data.frame.matrix(t(table(dat))) %>%
mutate(non_missing = 1) %>%
complete(A, B, C) %>%
group_by(A, B, C) %>%
summarize(Count = sum(ifelse(is.na(non_missing), 0, 1)))
结果:
# A tibble: 8 x 4
# Groups: A, B [?]
A B C Count
<dbl> <dbl> <dbl> <dbl>
1 0 0 0 0
2 0 0 1 2
3 0 1 0 0
4 0 1 1 2
5 1 0 0 2
6 1 0 1 0
7 1 1 0 2
8 1 1 1 1
我们有
xxtabs <- function(df, formula) {
xt <- xtabs(formula, df)
xxt <- xtabs( ~ . , as.data.frame.matrix(xt))
as.data.frame(xxt)
}
和
> xxtabs(dat, ~ animals + categories)
A B C Freq
1 0 0 0 0
2 1 0 0 2
3 0 1 0 0
4 1 1 0 2
5 0 0 1 2
6 1 0 1 0
7 0 1 1 2
8 1 1 1 1
( dat
应该真正构造为data.frame(animals, categories)
)。 这种基本方法使用xtabs()
来形成第一个交叉表
xt <- xtabs(~ animals + categories, dat)
然后使用as.data.frame.matrix()
强制转换为第二个data.frame,并使用计算data.frame的所有列的第二个交叉制表。
xxt <- xtabs(~ ., as.data.frame.matrix(xt))
被迫达到理想的形式
as.data.frame(xxt)
我最初说这种方法是'奥术',因为它依赖于as.data.frame()
和as.data.frame.matrix()
之间差异的知识; 我认为xtabs()
是基础R的用户应该知道的工具。 我看到其他解决方案也需要这些神秘的知识,以及更多模糊(例如, complete()
, group_by_all()
,funs funs()
)tidyverse部分的知识。 此外,其他答案不是(或至少不是以允许的方式编写)容易推广; xxtabs()
实际上并不知道有关传入data.frame结构的任何信息,而传入数据的隐含知识存在于其他答案中。
从整洁的方法中学到的一个“经验教训”是首先放置数据参数,允许管道
dat %>% xxtabs(~ animals + categories)
如果我理解正确,这应该可以解决问题。
require(tidyverse)
dat %>%
mutate(value = 1) %>%
spread(categories, value) %>%
mutate_if(is.numeric, funs(replace(., is.na(.), 0))) %>%
mutate(count = rowSums(data.frame(A, B, C), na.rm = TRUE)) %>%
group_by(A, B, C) %>%
summarize(Count = n())
# A tibble: 5 x 4
# Groups: A, B [?]
A B C Count
<dbl> <dbl> <dbl> <int>
1 0. 0. 1. 2
2 0. 1. 1. 2
3 1. 0. 0. 2
4 1. 1. 0. 2
5 1. 1. 1. 1
添加data.table
解决方案。 首先,使用dat将动物与类别联系起来。 然后,使用CJ
创建A,B,C的组合。 将这些组合与dat连接起来,并计算每个组合的出现次数。
dcast(as.data.table(dat), animals ~ categories, length)[
CJ(A=0:1, B=0:1, C=0:1), .(count=.N), on=c("A","B","C"), by=.EACHI]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.