R 如何根据列中的级别对循环值求和并输出计数表?

R 如何根据列中的级别对循环值求和并输出计数表?,r,R,我是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,a

我是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)
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,因为“猫”是每个类别中唯一重复自己的动物


R中是否有一个函数可以帮助我实现这一点?提前谢谢你。

如果我没听错,这就可以了

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
require(tidyverse)
dat%>%
变异(值=1)%>%
价差(类别、价值)%>%
如果(is.numeric,funs(replace(.,is.na(.,0)))%>
mutate(count=rowSums(data.frame(A,B,C),na.rm=TRUE))%>%
(A、B、C)组%>%
汇总(计数=n())
#一个tibble:5x4
#组:A、B[?]
A B C计数
1    0.    01.2.
2    0.    1.1.2.
3    1.    002.
4    1.    1.02.
5    1.    1.1.1.

我们可以使用
表格
创建
类别
动物
的交叉表格,转置,转换为data.frame,
分组
所有
类别
并计算每个组合的频率:

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
# 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
或者使用@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: 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
# 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
#一个tible:8 x 4
#组:A、B[?]
A B C计数
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)
}
dat
实际上应该被构造为
data.frame(动物、类别)
)。这种基本方法使用
xtabs()
形成第一个交叉表格

xt <- xtabs(~ animals + categories, dat)
强迫到想要的形式

as.data.frame(xxt)
我最初说这种方法是“神秘的”,因为它依赖于对
as.data.frame()
as.data.frame.matrix()之间差异的了解;我认为
xtabs()
是base R用户应该知道的工具。我认为其他的解决方案也需要这种神秘的知识,以及更晦涩的知识(例如,
complete()
groupby\u all()
funs()
)的tidyverse部分。此外,其他答案也不容易概括(或至少没有以允许的方式书写)
xxtabs()
实际上并不知道有关传入data.frame结构的任何信息,而传入数据的隐含知识在其他答案中都存在

从tidy方法中得到的一个“教训”是首先放置数据参数,允许使用管道

dat %>% xxtabs(~ animals + categories)

添加
数据表
解决方案。首先,使用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]

与预期输出不匹配。@C.Braun-感谢您的评论。请参阅my edit.FYI,如果您还想包括
count=0
的组,这并不简单,因为
dplyr::group_by()
中没有类似于
drop=FALSE
的内容。这里有一些解决方法:包括所有可能的行的一种方法是在
groupby
之前包括所有选项:
bind\u行(expand.grid(A=c(0,1),B=c(0,1),c=c(0,1))
然后将
n()
更改为
n()-1
@qdread Yea,我正试图弄清楚这一点。问题是这些组合实际上并没有出现在
表中,因此没有任何东西可以
删除
@C.Braun好主意!让我把它添加到答案中。@Ryan是的,我可以使用
complete
,但我必须为添加的最初隐含的缺失行添加一个指示符。使用C.Braun的方法,我添加了A、B和C的所有可能组合,因此我在最后要做的就是在计数时
-1
。请参阅我的更新。“了解tidyverse中更模糊的部分(例如,complete()、group_by_all()、funs())。也许对你来说是这样,但它们仍然比许多基本的R函数更容易理解,IMHO(这是tidyverse的主要目标之一)@useR我完全支持tidyverse提供的一致性,但难道没有更简单的解决方案吗?这些函数使用了约10个函数,而base R只使用了3个。期待您的实施!并不是说越多越好,但是
tidyverse
更具表现力、更易于编写/遵循的原因正是因为它将一个操作分解为多个较小的步骤。这完全取决于你在找什么。当然,如果你想最小化代码,带3个函数的Base R是不错的选择,但我认为学习
tidyverse
的每个步骤比学习许多Base R函数的细微差别更直观,因为在很多情况下,Base R函数做事情是隐式的,不太一致。我同意你的回答更笼统。
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]